Skip to content

Commit 1406954

Browse files
authored
Merge pull request #91 from SectorLabs/immutable-slugs
Add a flag to make LocalizedUniqueSlugField immutable
2 parents 7ba0ff6 + afb94ec commit 1406954

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

localized_fields/fields/uniqueslug_field.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,19 @@ class LocalizedUniqueSlugField(LocalizedAutoSlugField):
2121
When in doubt, use this over :see:LocalizedAutoSlugField.
2222
Inherit from :see:AtomicSlugRetryMixin in your model to
2323
make this field work properly.
24+
25+
By default, this creates a new slug if the field(s) specified
26+
in `populate_from` are changed. Set `immutable=True` to get
27+
immutable slugs.
2428
"""
2529

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

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

35+
self.immutable = kwargs.pop("immutable", False)
36+
3137
super(LocalizedUniqueSlugField, self).__init__(*args, **kwargs)
3238

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

4349
kwargs["populate_from"] = self.populate_from
4450
kwargs["include_time"] = self.include_time
51+
52+
if self.immutable is True:
53+
kwargs["immutable"] = self.immutable
54+
4555
return name, path, args, kwargs
4656

4757
def pre_save(self, instance, add: bool):
@@ -76,10 +86,14 @@ def pre_save(self, instance, add: bool):
7686

7787
slug = slugify(value, allow_unicode=True)
7888

89+
current_slug = getattr(instance, self.name).get(lang_code)
90+
if current_slug and self.immutable:
91+
slugs.set(lang_code, current_slug)
92+
continue
93+
7994
# verify whether it's needed to re-generate a slug,
8095
# if not, re-use the same slug
8196
if instance.pk is not None:
82-
current_slug = getattr(instance, self.name).get(lang_code)
8397
if current_slug is not None:
8498
current_slug_end_index = current_slug.rfind("-")
8599
stripped_slug = current_slug[0:current_slug_end_index]

tests/test_slug_fields.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,32 @@ def test_populate_multiple_languages(cls):
215215
for lang_code, lang_name in settings.LANGUAGES:
216216
assert obj.slug.get(lang_code) == "title-%s" % lang_name.lower()
217217

218+
@classmethod
219+
def test_allows_override_when_immutable(cls):
220+
"""Tests whether setting a value manually works and does not get
221+
overriden."""
222+
223+
Model = get_fake_model(
224+
{
225+
"title": LocalizedField(),
226+
"name": models.CharField(max_length=255),
227+
"slug": LocalizedUniqueSlugField(
228+
populate_from="title", immutable=True
229+
),
230+
}
231+
)
232+
233+
obj = Model()
234+
235+
for lang_code, lang_name in settings.LANGUAGES:
236+
obj.slug.set(lang_code, "my value %s" % lang_code)
237+
obj.title.set(lang_code, "my title %s" % lang_code)
238+
239+
obj.save()
240+
241+
for lang_code, lang_name in settings.LANGUAGES:
242+
assert obj.slug.get(lang_code) == "my value %s" % lang_code
243+
218244
@classmethod
219245
def test_unique_slug(cls):
220246
"""Tests whether unique slugs are properly generated."""

0 commit comments

Comments
 (0)