Skip to content

Commit fef6923

Browse files
committed
Merge branch 'master' into UPDATE_explicit_language_duplicates_validation
2 parents bcc67b9 + 862d4f5 commit fef6923

File tree

7 files changed

+83
-2
lines changed

7 files changed

+83
-2
lines changed

docs/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Table of contents
2424
:caption: Documentation
2525

2626
pages/getting-started
27+
pages/working-with-models
2728
pages/performance
2829
pages/inner-workings
2930
pages/known-issues

docs/pages/working-with-models.rst

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Working with models recipes.
2+
============================
3+
4+
Inheritance of translation models.
5+
----------------------------------
6+
7+
In case when you are working with models Inheritance and you want to change
8+
behavior of TranslationField declared in parent model, you should use
9+
`i18n_field_params` attribute and declare there parameters
10+
for child model field.
11+
12+
Example of use: ::
13+
14+
class ParentModel(models.Model):
15+
info = models.CharField(max_length=255)
16+
17+
i18n = TranslationField(fields=("info", ), required_languages=("en",))
18+
19+
20+
class ChildModel(ParentModel):
21+
child_info = models.CharField(max_length=255)
22+
23+
i18n_field_params = {
24+
"fields": ("info", "child_info"),
25+
"required_languages": ("nl",)
26+
}

modeltrans/translator.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ def get_translated_models(app_name):
3535
yield model
3636

3737

38+
def get_i18n_field_param(Model, i18n_field, param_name):
39+
"""
40+
Return i18n_param from Model.i18n_field_params dict if exists
41+
or get param from i18n_field
42+
"""
43+
if hasattr(Model, "i18n_field_params") and param_name in Model.i18n_field_params:
44+
return Model.i18n_field_params[param_name]
45+
return getattr(i18n_field, param_name)
46+
47+
3848
def translate_model(Model):
3949
i18n_field = get_i18n_field(Model)
4050

@@ -52,7 +62,9 @@ def translate_model(Model):
5262
validate(Model)
5363

5464
add_manager(Model)
55-
add_virtual_fields(Model, i18n_field.fields, i18n_field.required_languages)
65+
fields_to_translate = get_i18n_field_param(Model, i18n_field, "fields")
66+
required_languages = get_i18n_field_param(Model, i18n_field, "required_languages")
67+
add_virtual_fields(Model, fields_to_translate, required_languages)
5668
patch_constructor(Model)
5769

5870
translate_meta_ordering(Model)

tests/app/models.py

+9
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,12 @@ class Meta:
158158
class Article(AbstractArticle):
159159

160160
pass
161+
162+
163+
class ChildArticle(Article):
164+
"""
165+
Child Article for Django Models Inheritance testing
166+
"""
167+
168+
child_title = models.CharField(max_length=255)
169+
i18n_field_params = {"fields": ["title", "child_title"], "required_languages": ("nl",)}

tests/test_models.py

+28-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from django.utils.translation import override
99

1010
from modeltrans.fields import TranslationField
11-
from tests.app.models import Blog, NullableTextModel, TextModel
11+
from tests.app.models import Article, Blog, ChildArticle, NullableTextModel, TextModel
1212

1313
from .utils import CreateTestModel
1414

@@ -268,6 +268,33 @@ def test_defer_i18n(self):
268268
blog.title_i18n
269269

270270

271+
class TranslatedFieldInheritanceTest(TestCase):
272+
def test_child_model_i18n_fields(self):
273+
self.assertFalse(hasattr(Article, "child_title_nl"))
274+
self.assertTrue(hasattr(ChildArticle, "child_title_nl"))
275+
276+
def test_child_model_required_languages(self):
277+
self.assertTrue(Article._meta.get_field("title_nl").blank)
278+
self.assertFalse(ChildArticle._meta.get_field("title_nl").blank)
279+
280+
def test_diff_i18n_parent_child_models_instances(self):
281+
"""
282+
Test different behavior of Article and ChildArticle instances
283+
"""
284+
article = Article(title="Title")
285+
article.full_clean()
286+
article.save()
287+
child_article = ChildArticle(title="Title", child_title="Child title")
288+
with self.assertRaises(ValidationError):
289+
child_article.full_clean()
290+
child_article.title_nl = "Title NL"
291+
child_article.child_title_nl = "Child title NL"
292+
child_article.full_clean()
293+
child_article.save()
294+
self.assertFalse("child_title_nl" in article.i18n)
295+
self.assertTrue("child_title_nl" in child_article.i18n)
296+
297+
271298
class RefreshFromDbTest(TestCase):
272299
def test_refresh_from_db(self):
273300
b = Blog.objects.create(title="Falcon", i18n={"title_nl": "Valk", "title_de": "Falk"})

tests/test_translating.py

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def test_get_translated_models(self):
3838
expected = {
3939
app_models.Article,
4040
app_models.Blog,
41+
app_models.ChildArticle,
4142
app_models.Category,
4243
app_models.Person,
4344
app_models.TextModel,

tox.ini

+5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ basepython =
2020
py35: python3.5
2121
py36: python3.6
2222
py37: python3.7
23+
24+
# workaround for Error installing '...django-tables2': editable mode is not supported for pyproject.toml-style projects.
25+
# https://github.com/pypa/pip/issues/6434
26+
install_command = python -m pip install --no-use-pep517 {opts} {packages}
27+
2328
usedevelop = true
2429
pip_pre = true
2530
setenv =

0 commit comments

Comments
 (0)