add ability for page.copy to copy ParentalManyToMany field relations

pull/5112/head
LB Johnston 2019-02-27 08:04:56 +10:00
rodzic 233bb17789
commit fa2a0c2d02
4 zmienionych plików z 49 dodań i 3 usunięć

Wyświetl plik

@ -20,6 +20,7 @@ Changelog
* Fix: Parent page link in page chooser search results no longer navigates away (Asanka Lihiniyagoda, Sævar Öfjörð Magnússon)
* Fix: `routablepageurl` tag now correctly omits domain part when multiple sites exist at the same root (Gassan Gousseinov)
* Fix: Added missing collection column specifier on document listing template (Sergey Fedoseev)
* Fix: Page Copy will now also copy ParentalManyToMany field relations (LB (Ben Johnston))
2.4 (19.12.2018)

Wyświetl plik

@ -35,6 +35,7 @@ Bug fixes
* Parent page link in page chooser search results no longer navigates away (Asanka Lihiniyagoda, Sævar Öfjörð Magnússon)
* ``routablepageurl`` tag now correctly omits domain part when multiple sites exist at the same root (Gassan Gousseinov)
* Added missing collection column specifier on document listing template (Sergey Fedoseev)
* Page Copy will now also copy ParentalManyToMany field relations (LB (Ben Johnston))
Upgrade considerations

Wyświetl plik

@ -22,7 +22,8 @@ from django.utils import timezone
from django.utils.functional import cached_property
from django.utils.text import capfirst, slugify
from django.utils.translation import ugettext_lazy as _
from modelcluster.models import ClusterableModel, get_all_child_relations
from modelcluster.models import (
ClusterableModel, get_all_child_m2m_relations, get_all_child_relations)
from treebeard.mp_tree import MP_Node
from wagtail.core.query import PageQuerySet, TreeQuerySet
@ -1070,6 +1071,14 @@ class Page(AbstractPage, index.Indexed, ClusterableModel, metaclass=PageBase):
specific_dict[field.name] = getattr(specific_self, field.name)
# copy child m2m relations
for related_field in get_all_child_m2m_relations(specific_self):
field = getattr(specific_self, related_field.name)
if field and hasattr(field, 'all'):
values = field.all()
if values:
specific_dict[related_field.name] = values
# New instance from prepared dict values, in case the instance class implements multiple levels inheritance
page_copy = self.specific_class(**specific_dict)

Wyświetl plik

@ -16,8 +16,8 @@ from wagtail.core.models import Page, PageManager, Site, get_page_models
from wagtail.tests.testapp.models import (
AbstractPage, Advert, AlwaysShowInMenusPage, BlogCategory, BlogCategoryBlogPage, BusinessChild,
BusinessIndex, BusinessNowherePage, BusinessSubIndex, CustomManager, CustomManagerPage,
CustomPageQuerySet, EventIndex, EventPage, GenericSnippetPage, ManyToManyBlogPage, MTIBasePage,
MTIChildPage, MyCustomPage, OneToOnePage, PageWithExcludedCopyField, SimplePage,
CustomPageQuerySet, EventCategory, EventIndex, EventPage, GenericSnippetPage, ManyToManyBlogPage,
MTIBasePage, MTIChildPage, MyCustomPage, OneToOnePage, PageWithExcludedCopyField, SimplePage,
SingleEventPage, SingletonPage, StandardIndex, TaggedPage)
from wagtail.tests.utils import WagtailTestUtils
@ -702,6 +702,41 @@ class TestCopyPage(TestCase):
"Child objects defined on the superclass were removed from the original page"
)
def test_copy_page_copies_parental_relations(self):
"""Test that a page will be copied with parental many to many relations intact."""
christmas_event = EventPage.objects.get(url_path='/home/events/christmas/')
summer_category = EventCategory.objects.create(name='Summer')
holiday_category = EventCategory.objects.create(name='Holidays')
# add parental many to many relations
christmas_event.categories = (summer_category, holiday_category)
christmas_event.save()
# Copy it
new_christmas_event = christmas_event.copy(
update_attrs={'title': "New christmas event", 'slug': 'new-christmas-event'}
)
# check that original eventt is untouched
self.assertEqual(
christmas_event.categories.count(),
2,
"Child objects (parental many to many) defined on the superclass were removed from the original page"
)
# check that parental many to many are copied
self.assertEqual(
new_christmas_event.categories.count(),
2,
"Child objects (parental many to many) weren't copied"
)
# check that the original and copy are related to the same categories
self.assertEqual(
new_christmas_event.categories.all().in_bulk(),
christmas_event.categories.all().in_bulk()
)
def test_copy_page_copies_revisions(self):
christmas_event = EventPage.objects.get(url_path='/home/events/christmas/')
christmas_event.save_revision()