mirror of
https://github.com/SectorLabs/django-localized-fields.git
synced 2025-04-25 11:42:54 +03:00
Add option include_time to LocalizedUniqueSlugField
This commit is contained in:
parent
64c3c06612
commit
ca6b1c88fa
@ -212,6 +212,15 @@ Besides ``LocalizedField``, there's also:
|
|||||||
title = LocalizedField()
|
title = LocalizedField()
|
||||||
slug = LocalizedUniqueSlugField(populate_from='title')
|
slug = LocalizedUniqueSlugField(populate_from='title')
|
||||||
|
|
||||||
|
By setting the option ``include_time=True``
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
slug = LocalizedUniqueSlugField(populate_from='title', include_time=True)
|
||||||
|
|
||||||
|
You can instruct the field to include a part of the current time into
|
||||||
|
the resulting slug. This is useful if you're running into a lot of collisions.
|
||||||
|
|
||||||
* ``LocalizedAutoSlugField``
|
* ``LocalizedAutoSlugField``
|
||||||
Automatically creates a slug for every language from the specified field.
|
Automatically creates a slug for every language from the specified field.
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -16,6 +17,7 @@ class LocalizedAutoSlugField(LocalizedField):
|
|||||||
"""Initializes a new instance of :see:LocalizedAutoSlugField."""
|
"""Initializes a new instance of :see:LocalizedAutoSlugField."""
|
||||||
|
|
||||||
self.populate_from = kwargs.pop('populate_from', None)
|
self.populate_from = kwargs.pop('populate_from', None)
|
||||||
|
self.include_time = kwargs.pop('include_time', False)
|
||||||
|
|
||||||
super(LocalizedAutoSlugField, self).__init__(
|
super(LocalizedAutoSlugField, self).__init__(
|
||||||
*args,
|
*args,
|
||||||
@ -30,6 +32,7 @@ class LocalizedAutoSlugField(LocalizedField):
|
|||||||
LocalizedAutoSlugField, self).deconstruct()
|
LocalizedAutoSlugField, self).deconstruct()
|
||||||
|
|
||||||
kwargs['populate_from'] = self.populate_from
|
kwargs['populate_from'] = self.populate_from
|
||||||
|
kwargs['include_time'] = self.include_time
|
||||||
return name, path, args, kwargs
|
return name, path, args, kwargs
|
||||||
|
|
||||||
def formfield(self, **kwargs):
|
def formfield(self, **kwargs):
|
||||||
@ -76,6 +79,9 @@ class LocalizedAutoSlugField(LocalizedField):
|
|||||||
if not value:
|
if not value:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if self.include_time:
|
||||||
|
value += '-%s' % datetime.now().microsecond
|
||||||
|
|
||||||
def is_unique(slug: str, language: str) -> bool:
|
def is_unique(slug: str, language: str) -> bool:
|
||||||
"""Gets whether the specified slug is unique."""
|
"""Gets whether the specified slug is unique."""
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ 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
|
||||||
@ -34,6 +36,18 @@ class LocalizedUniqueSlugField(LocalizedAutoSlugField):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.populate_from = kwargs.pop('populate_from')
|
self.populate_from = kwargs.pop('populate_from')
|
||||||
|
self.use_time = kwargs.pop('include_time', False)
|
||||||
|
|
||||||
|
def deconstruct(self):
|
||||||
|
"""Deconstructs the field into something the database
|
||||||
|
can store."""
|
||||||
|
|
||||||
|
name, path, args, kwargs = super(
|
||||||
|
LocalizedUniqueSlugField, self).deconstruct()
|
||||||
|
|
||||||
|
kwargs['populate_from'] = self.populate_from
|
||||||
|
kwargs['include_time'] = self.include_time
|
||||||
|
return name, path, args, kwargs
|
||||||
|
|
||||||
def pre_save(self, instance, add: bool):
|
def pre_save(self, instance, add: bool):
|
||||||
"""Ran just before the model is saved, allows us to built
|
"""Ran just before the model is saved, allows us to built
|
||||||
@ -70,6 +84,9 @@ class LocalizedUniqueSlugField(LocalizedAutoSlugField):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
slug = slugify(value, allow_unicode=True)
|
slug = slugify(value, allow_unicode=True)
|
||||||
|
if self.include_time:
|
||||||
|
slug += '-%d' % datetime.now().microsecond
|
||||||
|
|
||||||
if instance.retries > 0:
|
if instance.retries > 0:
|
||||||
slug += '-%d' % instance.retries
|
slug += '-%d' % instance.retries
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ class LocalizedSlugFieldTestCase(TestCase):
|
|||||||
cls._test_populate(cls.AutoSlugModel)
|
cls._test_populate(cls.AutoSlugModel)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def test_populate_magic(cls):
|
def test_populate_unique(cls):
|
||||||
cls._test_populate(cls.MagicSlugModel)
|
cls._test_populate(cls.MagicSlugModel)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -51,7 +51,7 @@ class LocalizedSlugFieldTestCase(TestCase):
|
|||||||
cls._test_populate_multiple_languages(cls.AutoSlugModel)
|
cls._test_populate_multiple_languages(cls.AutoSlugModel)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def test_populate_multiple_languages_magic(cls):
|
def test_populate_multiple_languages_unique(cls):
|
||||||
cls._test_populate_multiple_languages(cls.MagicSlugModel)
|
cls._test_populate_multiple_languages(cls.MagicSlugModel)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -59,14 +59,35 @@ class LocalizedSlugFieldTestCase(TestCase):
|
|||||||
cls._test_unique_slug(cls.AutoSlugModel)
|
cls._test_unique_slug(cls.AutoSlugModel)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def test_unique_slug_magic(cls):
|
def test_unique_slug_unique(cls):
|
||||||
cls._test_unique_slug(cls.MagicSlugModel)
|
cls._test_unique_slug(cls.MagicSlugModel)
|
||||||
|
|
||||||
def test_unique_slug_magic_max_retries(self):
|
@staticmethod
|
||||||
"""Tests whether the magic slug implementation doesn't
|
def test_unique_slug_with_time():
|
||||||
|
"""Tests whether the primary key is included in
|
||||||
|
the slug when the 'use_pk' option is enabled."""
|
||||||
|
|
||||||
|
title = 'myuniquetitle'
|
||||||
|
|
||||||
|
PkModel = get_fake_model(
|
||||||
|
'PkModel',
|
||||||
|
{
|
||||||
|
'title': LocalizedField(),
|
||||||
|
'slug': LocalizedUniqueSlugField(populate_from='title', include_time=True)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
obj = PkModel()
|
||||||
|
obj.title.en = title
|
||||||
|
obj.save()
|
||||||
|
|
||||||
|
assert obj.slug.en.startswith('%s-' % title)
|
||||||
|
|
||||||
|
def test_unique_slug_unique_max_retries(self):
|
||||||
|
"""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."""
|
||||||
|
|
||||||
title = 'mymagictitle'
|
title = 'myuniquetitle'
|
||||||
|
|
||||||
obj = self.MagicSlugModel()
|
obj = self.MagicSlugModel()
|
||||||
obj.title.en = title
|
obj.title.en = title
|
||||||
@ -83,7 +104,7 @@ class LocalizedSlugFieldTestCase(TestCase):
|
|||||||
cls._test_unique_slug_utf(cls.AutoSlugModel)
|
cls._test_unique_slug_utf(cls.AutoSlugModel)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def test_unique_slug_utf_magic(cls):
|
def test_unique_slug_utf_unique(cls):
|
||||||
cls._test_unique_slug_utf(cls.MagicSlugModel)
|
cls._test_unique_slug_utf(cls.MagicSlugModel)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -91,7 +112,7 @@ class LocalizedSlugFieldTestCase(TestCase):
|
|||||||
cls._test_deconstruct(LocalizedAutoSlugField)
|
cls._test_deconstruct(LocalizedAutoSlugField)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def test_deconstruct_magic(cls):
|
def test_deconstruct_unique(cls):
|
||||||
cls._test_deconstruct(LocalizedUniqueSlugField)
|
cls._test_deconstruct(LocalizedUniqueSlugField)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -99,7 +120,7 @@ class LocalizedSlugFieldTestCase(TestCase):
|
|||||||
cls._test_formfield(LocalizedAutoSlugField)
|
cls._test_formfield(LocalizedAutoSlugField)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def test_formfield_magic(cls):
|
def test_formfield_unique(cls):
|
||||||
cls._test_formfield(LocalizedUniqueSlugField)
|
cls._test_formfield(LocalizedUniqueSlugField)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -130,7 +151,7 @@ class LocalizedSlugFieldTestCase(TestCase):
|
|||||||
def _test_unique_slug(model):
|
def _test_unique_slug(model):
|
||||||
"""Tests whether unique slugs are properly generated."""
|
"""Tests whether unique slugs are properly generated."""
|
||||||
|
|
||||||
title = 'mymagictitle'
|
title = 'myuniquetitle'
|
||||||
|
|
||||||
obj = model()
|
obj = model()
|
||||||
obj.title.en = title
|
obj.title.en = title
|
||||||
|
Loading…
x
Reference in New Issue
Block a user