Passed
Push — master ( ad2ef3...2e9b83 )
by Swen
01:47
created

LocalizedUniqueSlugField.pre_save()   B

Complexity

Conditions 6

Size

Total Lines 45

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 6.0087

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
c 2
b 0
f 0
dl 0
loc 45
ccs 15
cts 16
cp 0.9375
crap 6.0087
rs 7.5384
1 1
from django.conf import settings
2 1
from django.utils.text import slugify
3 1
from django.core.exceptions import ImproperlyConfigured
4
5 1
from ..util import get_language_codes
6 1
from ..mixins import AtomicSlugRetryMixin
7 1
from ..localized_value import LocalizedValue
8 1
from .localized_autoslug_field import LocalizedAutoSlugField
9
10 1
from datetime import datetime
0 ignored issues
show
introduced by
standard import "from datetime import datetime" comes before "from django.conf import settings"
Loading history...
11
12
13 1
class LocalizedUniqueSlugField(LocalizedAutoSlugField):
14
    """Automatically provides slugs for a localized
15
    field upon saving."
16
17
    An improved version of :see:LocalizedAutoSlugField,
18
    which adds:
19
20
        - Concurrency safety
21
        - Improved performance
22
23
    When in doubt, use this over :see:LocalizedAutoSlugField.
24
    Inherit from :see:AtomicSlugRetryMixin in your model to
25
    make this field work properly.
26
    """
27
28 1
    def __init__(self, *args, **kwargs):
29
        """Initializes a new instance of :see:LocalizedUniqueSlugField."""
30
31 1
        kwargs['uniqueness'] = kwargs.pop('uniqueness', get_language_codes())
32
33 1
        super(LocalizedUniqueSlugField, self).__init__(
34
            *args,
35
            **kwargs
36
        )
37
38 1
        self.populate_from = kwargs.pop('populate_from')
39 1
        self.include_time = kwargs.pop('include_time', False)
40
41 1
    def deconstruct(self):
42
        """Deconstructs the field into something the database
43
        can store."""
44
45 1
        name, path, args, kwargs = super(
46
            LocalizedUniqueSlugField, self).deconstruct()
47
48 1
        kwargs['populate_from'] = self.populate_from
49 1
        kwargs['include_time'] = self.include_time
50
        # if not kwargs['include_time']:
51
        #     raise RuntimeError()
52 1
        return name, path, args, kwargs
53
54 1
    def pre_save(self, instance, add: bool):
55
        """Ran just before the model is saved, allows us to built
56
        the slug.
57
58
        Arguments:
59
            instance:
60
                The model that is being saved.
61
62
            add:
63
                Indicates whether this is a new entry
64
                to the database or an update.
65
66
        Returns:
67
            The localized slug that was generated.
68
        """
69
70 1
        if not isinstance(instance, AtomicSlugRetryMixin):
71
            raise ImproperlyConfigured((
72
                'Model \'%s\' does not inherit from AtomicSlugRetryMixin. '
73
                'Without this, the LocalizedUniqueSlugField will not work.'
74
            ) % type(instance).__name__)
75
76 1
        slugs = LocalizedValue()
77
78 1
        for lang_code, _ in settings.LANGUAGES:
79 1
            value = self._get_populate_from_value(
80
                instance,
81
                self.populate_from,
82
                lang_code
83
            )
84
85 1
            if not value:
86 1
                continue
87
88 1
            slug = slugify(value, allow_unicode=True)
89 1
            if self.include_time:
90 1
                slug += '-%d' % datetime.now().microsecond
91
92 1
            if instance.retries > 0:
93 1
                slug += '-%d' % instance.retries
94
95 1
            slugs.set(lang_code, slug)
96
97 1
        setattr(instance, self.name, slugs)
98
        return slugs
99