kopia lustrzana https://github.com/wagtail/wagtail
Fix copy_for_translation on inherited and clusterable models
rodzic
a02e7b28b8
commit
e05081a1ab
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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')},
|
||||
},
|
||||
),
|
||||
]
|
|
@ -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
|
||||
|
|
Ładowanie…
Reference in New Issue