0
0
mirror of https://github.com/wagtail/wagtail.git synced 2024-12-01 11:41:20 +01:00

Merge branch 'kaedroho-fix-1418'

This commit is contained in:
Matt Westcott 2015-09-03 15:20:35 +01:00
commit fb559c0cea
2 changed files with 23 additions and 2 deletions

View File

@ -2,6 +2,7 @@ from __future__ import unicode_literals
import logging
import json
from collections import defaultdict
from modelcluster.models import ClusterableModel, get_all_child_relations
@ -814,18 +815,27 @@ class Page(six.with_metaclass(PageBase, MP_Node, ClusterableModel, index.Indexed
else:
page_copy = self.add_sibling(instance=page_copy)
# A dict that maps child objects to their new ids
# Used to remap child object ids in revisions
child_object_id_map = defaultdict(dict)
# Copy child objects
specific_self = self.specific
for child_relation in get_all_child_relations(specific_self):
accessor_name = child_relation.get_accessor_name()
parental_key_name = child_relation.field.attname
child_objects = getattr(specific_self, child_relation.get_accessor_name(), None)
child_objects = getattr(specific_self, accessor_name, None)
if child_objects:
for child_object in child_objects.all():
old_pk = child_object.pk
child_object.pk = None
setattr(child_object, parental_key_name, page_copy.id)
child_object.save()
# Add mapping to new primary key (so we can apply this change to revisions)
child_object_id_map[accessor_name][old_pk] = child_object.pk
# Copy revisions
if copy_revisions:
for revision in self.revisions.all():
@ -839,8 +849,9 @@ class Page(six.with_metaclass(PageBase, MP_Node, ClusterableModel, index.Indexed
revision_content['pk'] = page_copy.pk
for child_relation in get_all_child_relations(specific_self):
accessor_name = child_relation.get_accessor_name()
try:
child_objects = revision_content[child_relation.get_accessor_name()]
child_objects = revision_content[accessor_name]
except KeyError:
# KeyErrors are possible if the revision was created
# before this child relation was added to the database
@ -849,6 +860,11 @@ class Page(six.with_metaclass(PageBase, MP_Node, ClusterableModel, index.Indexed
for child_object in child_objects:
child_object[child_relation.field.name] = page_copy.pk
# Remap primary key to copied versions
# If the primary key is not recognised (eg, the child object has been deleted from the database)
# set the primary key to None
child_object['pk'] = child_object_id_map[accessor_name].get(child_object['pk'], None)
revision.content_json = json.dumps(revision_content)
# Save

View File

@ -448,6 +448,11 @@ class TestCopyPage(TestCase):
self.assertEqual(new_revision_content['pk'], new_christmas_event.id)
self.assertEqual(new_revision_content['speakers'][0]['page'], new_christmas_event.id)
# Also, check that the child objects in the new revision are given new IDs
old_speakers_ids = set(christmas_event.speakers.values_list('id', flat=True))
new_speakers_ids = set(speaker['pk'] for speaker in new_revision_content['speakers'])
self.assertFalse(old_speakers_ids.intersection(new_speakers_ids), "Child objects in revisions were not given a new primary key")
def test_copy_page_copies_revisions_and_doesnt_submit_for_moderation(self):
christmas_event = EventPage.objects.get(url_path='/home/events/christmas/')
christmas_event.save_revision(submitted_for_moderation=True)