Skip to content

Commit

Permalink
Merge pull request #91 from SectorLabs/immutable-slugs
Browse files Browse the repository at this point in the history
Add a flag to make LocalizedUniqueSlugField immutable
  • Loading branch information
Photonios committed Nov 30, 2020
2 parents 7ba0ff6 + afb94ec commit 1406954
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
16 changes: 15 additions & 1 deletion localized_fields/fields/uniqueslug_field.py
Expand Up @@ -21,13 +21,19 @@ class LocalizedUniqueSlugField(LocalizedAutoSlugField):
When in doubt, use this over :see:LocalizedAutoSlugField.
Inherit from :see:AtomicSlugRetryMixin in your model to
make this field work properly.
By default, this creates a new slug if the field(s) specified
in `populate_from` are changed. Set `immutable=True` to get
immutable slugs.
"""

def __init__(self, *args, **kwargs):
"""Initializes a new instance of :see:LocalizedUniqueSlugField."""

kwargs["uniqueness"] = kwargs.pop("uniqueness", get_language_codes())

self.immutable = kwargs.pop("immutable", False)

super(LocalizedUniqueSlugField, self).__init__(*args, **kwargs)

self.populate_from = kwargs.pop("populate_from")
Expand All @@ -42,6 +48,10 @@ def deconstruct(self):

kwargs["populate_from"] = self.populate_from
kwargs["include_time"] = self.include_time

if self.immutable is True:
kwargs["immutable"] = self.immutable

return name, path, args, kwargs

def pre_save(self, instance, add: bool):
Expand Down Expand Up @@ -76,10 +86,14 @@ def pre_save(self, instance, add: bool):

slug = slugify(value, allow_unicode=True)

current_slug = getattr(instance, self.name).get(lang_code)
if current_slug and self.immutable:
slugs.set(lang_code, current_slug)
continue

# 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:
current_slug_end_index = current_slug.rfind("-")
stripped_slug = current_slug[0:current_slug_end_index]
Expand Down
26 changes: 26 additions & 0 deletions tests/test_slug_fields.py
Expand Up @@ -215,6 +215,32 @@ def test_populate_multiple_languages(cls):
for lang_code, lang_name in settings.LANGUAGES:
assert obj.slug.get(lang_code) == "title-%s" % lang_name.lower()

@classmethod
def test_allows_override_when_immutable(cls):
"""Tests whether setting a value manually works and does not get
overriden."""

Model = get_fake_model(
{
"title": LocalizedField(),
"name": models.CharField(max_length=255),
"slug": LocalizedUniqueSlugField(
populate_from="title", immutable=True
),
}
)

obj = Model()

for lang_code, lang_name in settings.LANGUAGES:
obj.slug.set(lang_code, "my value %s" % lang_code)
obj.title.set(lang_code, "my title %s" % lang_code)

obj.save()

for lang_code, lang_name in settings.LANGUAGES:
assert obj.slug.get(lang_code) == "my value %s" % lang_code

@classmethod
def test_unique_slug(cls):
"""Tests whether unique slugs are properly generated."""
Expand Down

0 comments on commit 1406954

Please sign in to comment.