diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6289876..fb31b98 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,11 @@ CHANGELOG ========= +0.2.1 (20XX-XX-XX) +------------------ + +* Fix slug uniqueness check in TranslatedAutoSlugifyMixin + 0.2.0 (2015-10-22) ------------------ diff --git a/aldryn_translation_tools/models.py b/aldryn_translation_tools/models.py index e75b45a..a4a1ee6 100644 --- a/aldryn_translation_tools/models.py +++ b/aldryn_translation_tools/models.py @@ -175,6 +175,19 @@ def _get_slug_queryset(self, lookup_model=None): qs = qs.exclude(pk=self.pk) return qs + def _slug_exists(self, slug, slug_filter=None, qs=None): + """ + Check if slug exists in the given queryset. + If slug_filter is None it would be created from + self.raw_slug_filter_string and self.slug_field_name + """ + + if qs is None: + qs = self._get_slug_queryset() + if slug_filter is None: + slug_filter = self.raw_slug_filter_string.format(self.slug_field_name) + return qs.filter(**{slug_filter: slug}).exists() + def make_new_slug(self, slug=None, qs=None): """ Generate a slug that meets requirements. @@ -185,20 +198,17 @@ def make_new_slug(self, slug=None, qs=None): :return (str): slug """ - if qs is None: - qs = self._get_slug_queryset() - if slug is None: + if not slug: # Build the "ideal slug" for this object as a starting point slug = self._get_ideal_slug() # initial setup idx = 1 candidate = slug max_length = self.get_slug_max_length() - slug_filter = self.raw_slug_filter_string.format(self.slug_field_name) # Check if the resulting slug is currently in use, if not, use it. # Otherwise, add a separator and an index until we find an # unused combination. - while qs.filter(**{slug_filter: candidate}).exists(): + while self._slug_exists(candidate, qs=qs): if len(candidate) > max_length: max_length = self.get_slug_max_length(len(str(idx))) candidate = self._get_candidate_slug(slug[:max_length], idx) @@ -207,8 +217,8 @@ def make_new_slug(self, slug=None, qs=None): def save(self, **kwargs): slug = self._get_existing_slug() - if not slug: - slug = self.make_new_slug() + if not slug or self._slug_exists(slug): + slug = self.make_new_slug(slug=slug) setattr(self, self.slug_field_name, slug) return super(TranslatedAutoSlugifyMixin, self).save(**kwargs) diff --git a/tests/test_models.py b/tests/test_models.py index c8f31b8..6b13072 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -83,6 +83,34 @@ def test_slug_unique_global(self): self.assertEquals(simple_en.slug, simple_fr.slug) + def test_slug_unique_for_language(self): + simple_en_1 = Simple() + simple_en_1.set_current_language('en') + simple_en_1.name = 'SimpleOne' + simple_en_1.save() + # make another instance with same name + simple_en_2 = Simple() + simple_en_2.set_current_language('en') + simple_en_2.name = 'SimpleOne' + simple_en_2.save() + # slugs should not be same. + self.assertNotEquals(simple_en_1.slug, simple_en_2.slug) + + def test_slug_unique_for_language_if_slug_is_the_same(self): + simple_en_1 = Simple() + simple_en_1.set_current_language('en') + simple_en_1.name = 'SimpleOne' + simple_en_1.slug = 'simpleone' + simple_en_1.save() + # make another instance with same name + simple_en_2 = Simple() + simple_en_2.set_current_language('en') + simple_en_2.name = 'SimpleOne' + simple_en_2.slug = 'simpleone' + simple_en_2.save() + # slugs should not be same. + self.assertNotEquals(simple_en_1.slug, simple_en_2.slug) + def test_simple_slug_default(self): # First test that the default works simple = Simple()