mirror of
https://github.com/SectorLabs/django-localized-fields.git
synced 2025-04-25 03:32:55 +03:00
Support for slugging from multiple fields
This commit is contained in:
parent
3b28a5e707
commit
51fc6959d2
@ -1,12 +1,14 @@
|
|||||||
from typing import Callable, Tuple
|
from typing import Callable, Tuple, Union
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.utils import translation
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
|
|
||||||
from .field import LocalizedField
|
from .field import LocalizedField
|
||||||
from ..value import LocalizedValue
|
from ..value import LocalizedValue
|
||||||
|
from ..util import resolve_object_property
|
||||||
|
|
||||||
|
|
||||||
class LocalizedAutoSlugField(LocalizedField):
|
class LocalizedAutoSlugField(LocalizedField):
|
||||||
@ -147,7 +149,7 @@ class LocalizedAutoSlugField(LocalizedField):
|
|||||||
]
|
]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_populate_from_value(instance, field_name: str, language: str):
|
def _get_populate_from_value(instance, field_name: Union[str, Tuple[str]], language: str):
|
||||||
"""Gets the value to create a slug from in the specified language.
|
"""Gets the value to create a slug from in the specified language.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@ -164,5 +166,17 @@ class LocalizedAutoSlugField(LocalizedField):
|
|||||||
The text to generate a slug for.
|
The text to generate a slug for.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
value = getattr(instance, field_name, None)
|
def get_field_value(name):
|
||||||
return value.get(language)
|
value = resolve_object_property(instance, name)
|
||||||
|
with translation.override(language):
|
||||||
|
return str(value)
|
||||||
|
|
||||||
|
if isinstance(field_name, tuple) or isinstance(field_name, list):
|
||||||
|
value = '-'.join([
|
||||||
|
value
|
||||||
|
for value in [get_field_value(name) for name in field_name]
|
||||||
|
if value
|
||||||
|
])
|
||||||
|
return value
|
||||||
|
|
||||||
|
return get_field_value(field_name)
|
||||||
|
@ -19,3 +19,26 @@ def get_language_codes() -> List[str]:
|
|||||||
lang_code
|
lang_code
|
||||||
for lang_code, _ in settings.LANGUAGES
|
for lang_code, _ in settings.LANGUAGES
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_object_property(obj, path: str):
|
||||||
|
"""Resolves the value of a property on an object.
|
||||||
|
|
||||||
|
Is able to resolve nested properties. For example,
|
||||||
|
a path can be specified:
|
||||||
|
|
||||||
|
'other.beer.name'
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
AttributeError:
|
||||||
|
In case the property could not be resolved.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The value of the specified property.
|
||||||
|
"""
|
||||||
|
|
||||||
|
value = obj
|
||||||
|
for path_part in path.split('.'):
|
||||||
|
value = getattr(value, path_part)
|
||||||
|
|
||||||
|
return value
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import copy
|
import copy
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.db import models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.db.utils import IntegrityError
|
from django.db.utils import IntegrityError
|
||||||
@ -31,6 +32,7 @@ class LocalizedSlugFieldTestCase(TestCase):
|
|||||||
'LocalizedAutoSlugFieldTestModel',
|
'LocalizedAutoSlugFieldTestModel',
|
||||||
{
|
{
|
||||||
'title': LocalizedField(),
|
'title': LocalizedField(),
|
||||||
|
'name': models.CharField(max_length=255),
|
||||||
'slug': LocalizedAutoSlugField(populate_from='title')
|
'slug': LocalizedAutoSlugField(populate_from='title')
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -39,6 +41,7 @@ class LocalizedSlugFieldTestCase(TestCase):
|
|||||||
'LocalizedUniqueSlugFieldTestModel',
|
'LocalizedUniqueSlugFieldTestModel',
|
||||||
{
|
{
|
||||||
'title': LocalizedField(),
|
'title': LocalizedField(),
|
||||||
|
'name': models.CharField(max_length=255),
|
||||||
'slug': LocalizedUniqueSlugField(populate_from='title')
|
'slug': LocalizedUniqueSlugField(populate_from='title')
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -155,6 +158,22 @@ class LocalizedSlugFieldTestCase(TestCase):
|
|||||||
def test_formfield_unique(cls):
|
def test_formfield_unique(cls):
|
||||||
cls._test_formfield(LocalizedUniqueSlugField)
|
cls._test_formfield(LocalizedUniqueSlugField)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def test_populate_multiple_from_fields_auto(cls):
|
||||||
|
cls._test_populate_multiple_from_fields(LocalizedAutoSlugField)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def test_populate_multiple_from_fields_unique(cls):
|
||||||
|
cls._test_populate_multiple_from_fields(LocalizedUniqueSlugField)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def test_populate_multiple_from_fields_fk_auto(cls):
|
||||||
|
cls._test_populate_multiple_from_fields_fk(LocalizedAutoSlugField)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def test_populate_multiple_from_fields_fk_unique(cls):
|
||||||
|
cls._test_populate_multiple_from_fields_fk(LocalizedUniqueSlugField)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _test_populate(model):
|
def _test_populate(model):
|
||||||
"""Tests whether the populating feature works correctly."""
|
"""Tests whether the populating feature works correctly."""
|
||||||
@ -165,6 +184,67 @@ class LocalizedSlugFieldTestCase(TestCase):
|
|||||||
|
|
||||||
assert obj.slug.get('en') == slugify(obj.title)
|
assert obj.slug.get('en') == slugify(obj.title)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _test_populate_multiple_from_fields(field_type):
|
||||||
|
"""Tests whether populating the slug from multiple
|
||||||
|
fields works correctly."""
|
||||||
|
|
||||||
|
model = get_fake_model(
|
||||||
|
'_test_populate_multiple_from_fields_' + str(field_type),
|
||||||
|
{
|
||||||
|
'title': LocalizedField(),
|
||||||
|
'name': models.CharField(max_length=255),
|
||||||
|
'slug': field_type(populate_from=('title', 'name'))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
obj = model()
|
||||||
|
for lang_code, lang_name in settings.LANGUAGES:
|
||||||
|
obj.name = 'swen'
|
||||||
|
obj.title.set(lang_code, 'title %s' % lang_name)
|
||||||
|
|
||||||
|
obj.save()
|
||||||
|
|
||||||
|
for lang_code, lang_name in settings.LANGUAGES:
|
||||||
|
assert obj.slug.get(lang_code) == 'title-%s-swen' % lang_name.lower()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _test_populate_multiple_from_fields_fk(field_type):
|
||||||
|
"""Tests whether populating the slug from multiple
|
||||||
|
fields works correctly."""
|
||||||
|
|
||||||
|
model_fk = get_fake_model(
|
||||||
|
'_test_populate_multiple_from_fields_fk_other_' + str(field_type),
|
||||||
|
{
|
||||||
|
'name': LocalizedField(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
model = get_fake_model(
|
||||||
|
'_test_populate_multiple_from_fields_fk_' + str(field_type),
|
||||||
|
{
|
||||||
|
'title': LocalizedField(),
|
||||||
|
'other': models.ForeignKey(model_fk),
|
||||||
|
'slug': field_type(populate_from=('title', 'other.name'))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
other = model_fk.objects.create(name={settings.LANGUAGE_CODE: 'swen'})
|
||||||
|
# for lang_code, lang_name in settings.LANGUAGES:
|
||||||
|
# other.name.set(lang_code, 'swen')
|
||||||
|
|
||||||
|
# other.save()
|
||||||
|
|
||||||
|
obj = model()
|
||||||
|
for lang_code, lang_name in settings.LANGUAGES:
|
||||||
|
obj.other_id = other.id
|
||||||
|
obj.title.set(lang_code, 'title %s' % lang_name)
|
||||||
|
|
||||||
|
obj.save()
|
||||||
|
|
||||||
|
for lang_code, lang_name in settings.LANGUAGES:
|
||||||
|
assert obj.slug.get(lang_code) == 'title-%s-swen' % lang_name.lower()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _test_populate_multiple_languages(model):
|
def _test_populate_multiple_languages(model):
|
||||||
"""Tests whether the populating feature correctly
|
"""Tests whether the populating feature correctly
|
||||||
|
Loading…
x
Reference in New Issue
Block a user