Don't regenerate slug if not needed

This commit is contained in:
Swen Kooij 2017-02-16 10:13:10 +02:00
parent 2e9b83e49b
commit 6d7a937eac
2 changed files with 47 additions and 7 deletions

View File

@ -1,3 +1,5 @@
from datetime import datetime
from django.conf import settings from django.conf import settings
from django.utils.text import slugify from django.utils.text import slugify
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
@ -7,8 +9,6 @@ from ..mixins import AtomicSlugRetryMixin
from ..localized_value import LocalizedValue from ..localized_value import LocalizedValue
from .localized_autoslug_field import LocalizedAutoSlugField from .localized_autoslug_field import LocalizedAutoSlugField
from datetime import datetime
class LocalizedUniqueSlugField(LocalizedAutoSlugField): class LocalizedUniqueSlugField(LocalizedAutoSlugField):
"""Automatically provides slugs for a localized """Automatically provides slugs for a localized
@ -47,8 +47,6 @@ class LocalizedUniqueSlugField(LocalizedAutoSlugField):
kwargs['populate_from'] = self.populate_from kwargs['populate_from'] = self.populate_from
kwargs['include_time'] = self.include_time kwargs['include_time'] = self.include_time
# if not kwargs['include_time']:
# raise RuntimeError()
return name, path, args, kwargs return name, path, args, kwargs
def pre_save(self, instance, add: bool): def pre_save(self, instance, add: bool):
@ -86,11 +84,25 @@ class LocalizedUniqueSlugField(LocalizedAutoSlugField):
continue continue
slug = slugify(value, allow_unicode=True) slug = slugify(value, allow_unicode=True)
# verify whether it's needed to re-generate a slug,
# if not, re-use the same slug
if instance.pk is not None:
current_slug = getattr(instance, self.name).get(lang_code)
if current_slug is not None:
stripped_slug = current_slug[0:current_slug.rfind('-')]
if slug == stripped_slug:
slugs.set(lang_code, current_slug)
continue
if self.include_time: if self.include_time:
slug += '-%d' % datetime.now().microsecond slug += '-%d' % datetime.now().microsecond
if instance.retries > 0: if instance.retries > 0:
slug += '-%d' % instance.retries # do not add another - if we already added time
if not self.include_time:
slug += '-'
slug += '%d' % instance.retries
slugs.set(lang_code, slug) slugs.set(lang_code, slug)

View File

@ -1,11 +1,12 @@
import copy
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from django.test import TestCase from django.test import TestCase
from django.db.utils import IntegrityError from django.db.utils import IntegrityError
from django.utils.text import slugify
from localized_fields import (LocalizedField, LocalizedAutoSlugField, from localized_fields import (LocalizedField, LocalizedAutoSlugField,
LocalizedUniqueSlugField) LocalizedUniqueSlugField)
from django.utils.text import slugify
from .fake_model import get_fake_model from .fake_model import get_fake_model
@ -83,6 +84,33 @@ class LocalizedSlugFieldTestCase(TestCase):
assert obj.slug.en.startswith('%s-' % title) assert obj.slug.en.startswith('%s-' % title)
@classmethod
def test_uniue_slug_no_change(cls):
"""Tests whether slugs are not re-generated if not needed."""
NoChangeSlugModel = get_fake_model(
'NoChangeSlugModel',
{
'title': LocalizedField(),
'slug': LocalizedUniqueSlugField(populate_from='title', include_time=True)
}
)
title = 'myuniquetitle'
obj = NoChangeSlugModel()
obj.title.en = title
obj.title.nl = title
obj.save()
old_slug_en = copy.deepcopy(obj.slug.en)
old_slug_nl = copy.deepcopy(obj.slug.nl)
obj.title.nl += 'beer'
obj.save()
assert old_slug_en == obj.slug.en
assert old_slug_nl != obj.slug.nl
def test_unique_slug_unique_max_retries(self): def test_unique_slug_unique_max_retries(self):
"""Tests whether the unique slug implementation doesn't """Tests whether the unique slug implementation doesn't
try to find a slug forever and gives up after a while.""" try to find a slug forever and gives up after a while."""