Fix copy_for_translation on inherited and clusterable models

pull/6880/head
Karl Hobley 2021-02-16 18:12:51 +00:00 zatwierdzone przez Matt Westcott
rodzic a02e7b28b8
commit e05081a1ab
4 zmienionych plików z 132 dodań i 4 usunięć

Wyświetl plik

@ -152,7 +152,11 @@ def _copy(source, exclude_fields=None, update_attrs=None):
continue
setattr(target, field, value)
child_object_map = source.copy_all_child_relations(target, exclude=exclude_fields)
if isinstance(source, ClusterableModel):
child_object_map = source.copy_all_child_relations(target, exclude=exclude_fields)
else:
child_object_map = {}
return target, child_object_map
@ -491,10 +495,15 @@ class TranslatableMixin(models.Model):
Note that the copy is initially unsaved.
"""
translated = self.__class__.objects.get(id=self.id)
translated.id = None
translated, child_object_map = _copy(self)
translated.locale = locale
# Update locale on any translatable child objects as well
# Note: If this is not a subclass of ClusterableModel, child_object_map will always be '{}'
for (child_relation, old_pk), child_object in child_object_map.items():
if isinstance(child_object, TranslatableMixin):
child_object.locale = locale
return translated
def get_default_locale(self):

Wyświetl plik

@ -5,7 +5,9 @@ from django.core import checks
from django.test import TestCase
from wagtail.core.models import Locale
from wagtail.tests.i18n.models import InheritedTestModel, TestModel
from wagtail.tests.i18n.models import (
ClusterableTestModel, ClusterableTestModelChild, ClusterableTestModelTranslatableChild,
InheritedTestModel, TestModel)
def make_test_instance(model=None, **kwargs):
@ -108,6 +110,46 @@ class TestTranslatableMixin(TestCase):
inherited_model = make_test_instance(model=InheritedTestModel)
self.assertEqual(inherited_model.get_translation_model(), TestModel)
def test_copy_inherited_model_for_translation(self):
instance = make_test_instance(model=InheritedTestModel)
copy = instance.copy_for_translation(locale=self.another_locale)
self.assertNotEqual(copy, instance)
self.assertEqual(copy.translation_key, instance.translation_key)
self.assertEqual(copy.locale, self.another_locale)
def test_copy_clusterable_model_for_translation(self):
instance = ClusterableTestModel.objects.create(
title="A test clusterable model",
children=[
ClusterableTestModelChild(field="A non-translatable child object"),
],
translatable_children=[
ClusterableTestModelTranslatableChild(field="A translatable child object"),
]
)
copy = instance.copy_for_translation(locale=self.another_locale)
instance_child = instance.children.get()
copy_child = copy.children.get()
instance_translatable_child = instance.translatable_children.get()
copy_translatable_child = copy.translatable_children.get()
self.assertNotEqual(copy, instance)
self.assertEqual(copy.translation_key, instance.translation_key)
self.assertEqual(copy.locale, self.another_locale)
# Check children were copied
self.assertNotEqual(copy_child, instance_child)
self.assertEqual(copy_child.field, "A non-translatable child object")
self.assertNotEqual(copy_translatable_child, instance_translatable_child)
self.assertEqual(copy_translatable_child.field, "A translatable child object")
# Check the translatable childs locale was updated but translation key is the same
self.assertEqual(copy_translatable_child.translation_key, instance_translatable_child.translation_key)
self.assertEqual(copy_translatable_child.locale, self.another_locale)
class TestLocalized(TestCase):
def setUp(self):

Wyświetl plik

@ -0,0 +1,59 @@
# Generated by Django 3.1.6 on 2021-02-16 18:04
from django.db import migrations, models
import django.db.models.deletion
import modelcluster.fields
import uuid
class Migration(migrations.Migration):
dependencies = [
('wagtailcore', '0061_change_promote_tab_helpt_text_and_verbose_names'),
('i18n', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='ClusterableTestModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('translation_key', models.UUIDField(default=uuid.uuid4, editable=False)),
('title', models.CharField(max_length=255)),
('locale', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='wagtailcore.locale')),
],
options={
'abstract': False,
'unique_together': {('translation_key', 'locale')},
},
),
migrations.CreateModel(
name='ClusterableTestModelChild',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sort_order', models.IntegerField(blank=True, editable=False, null=True)),
('field', models.TextField()),
('parent', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='children', to='i18n.clusterabletestmodel')),
],
options={
'ordering': ['sort_order'],
'abstract': False,
},
),
migrations.CreateModel(
name='ClusterableTestModelTranslatableChild',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('translation_key', models.UUIDField(default=uuid.uuid4, editable=False)),
('sort_order', models.IntegerField(blank=True, editable=False, null=True)),
('field', models.TextField()),
('locale', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='wagtailcore.locale')),
('parent', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='translatable_children', to='i18n.clusterabletestmodel')),
],
options={
'ordering': ['sort_order'],
'abstract': False,
'unique_together': {('translation_key', 'locale')},
},
),
]

Wyświetl plik

@ -1,5 +1,6 @@
from django.db import models
from modelcluster.fields import ParentalKey
from modelcluster.models import ClusterableModel
from wagtail.core.models import Orderable, Page, TranslatableMixin
@ -30,3 +31,20 @@ class TestNonParentalChildObject(TranslatableMixin, Orderable):
TestPage, on_delete=models.CASCADE, related_name="test_nonparentalchildobjects"
)
field = models.TextField()
class ClusterableTestModel(TranslatableMixin, ClusterableModel):
title = models.CharField(max_length=255)
class ClusterableTestModelChild(Orderable):
parent = ParentalKey(ClusterableTestModel, on_delete=models.CASCADE, related_name='children')
field = models.TextField()
class ClusterableTestModelTranslatableChild(TranslatableMixin, Orderable):
parent = ParentalKey(ClusterableTestModel, on_delete=models.CASCADE, related_name='translatable_children')
field = models.TextField()
class Meta(TranslatableMixin.Meta, Orderable.Meta):
pass