Ensure variants are deleted for page decendants
This commit is contained in:
@ -4,6 +4,7 @@ import logging
|
|||||||
|
|
||||||
from django.conf.urls import include, url
|
from django.conf.urls import include, url
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
|
from django.db.models import F
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django.shortcuts import redirect, render
|
from django.shortcuts import redirect, render
|
||||||
from django.template.defaultfilters import pluralize
|
from django.template.defaultfilters import pluralize
|
||||||
@ -19,6 +20,7 @@ from wagtail.core.models import Page
|
|||||||
|
|
||||||
from wagtail_personalisation import admin_urls, models, utils
|
from wagtail_personalisation import admin_urls, models, utils
|
||||||
from wagtail_personalisation.adapters import get_segment_adapter
|
from wagtail_personalisation.adapters import get_segment_adapter
|
||||||
|
from wagtail_personalisation.models import PersonalisablePageMetadata
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -276,14 +278,22 @@ def delete_related_variants(request, page):
|
|||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
parent_id = page.get_parent().id
|
parent_id = page.get_parent().id
|
||||||
variants_metadata = variants_metadata.select_related('variant')
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
for metadata in variants_metadata.iterator():
|
# To ensure variants are deleted for all descendants, start with
|
||||||
# Call delete() on objects to trigger any signals or hooks.
|
# the deepest ones, and explicitly delete variants and metadata
|
||||||
metadata.variant.delete()
|
# for all of them, including the page itself. Otherwise protected
|
||||||
# Delete the page's main variant and the page itself.
|
# foreign key constraints are violated. Only consider canonical
|
||||||
page.personalisation_metadata.delete()
|
# pages.
|
||||||
page.delete()
|
for metadata in PersonalisablePageMetadata.objects.filter(
|
||||||
|
canonical_page__in=page.get_descendants(inclusive=True),
|
||||||
|
variant=F("canonical_page"),
|
||||||
|
).order_by('-canonical_page__depth'):
|
||||||
|
for variant_metadata in metadata.variants_metadata.select_related('variant'):
|
||||||
|
# Call delete() on objects to trigger any signals or hooks.
|
||||||
|
variant_metadata.variant.delete()
|
||||||
|
metadata.delete()
|
||||||
|
metadata.canonical_page.delete()
|
||||||
|
|
||||||
msg = _("Page '{0}' and its variants deleted.")
|
msg = _("Page '{0}' and its variants deleted.")
|
||||||
messages.success(
|
messages.success(
|
||||||
request,
|
request,
|
||||||
|
@ -4,6 +4,7 @@ from django.http import Http404
|
|||||||
|
|
||||||
from wagtail.core.models import Page
|
from wagtail.core.models import Page
|
||||||
|
|
||||||
|
from tests.factories.page import ContentPageFactory
|
||||||
from tests.factories.segment import SegmentFactory
|
from tests.factories.segment import SegmentFactory
|
||||||
from wagtail_personalisation import adapters, wagtail_hooks
|
from wagtail_personalisation import adapters, wagtail_hooks
|
||||||
|
|
||||||
@ -124,3 +125,21 @@ def test_custom_delete_page_view_deletes_variants(rf, segmented_page, user):
|
|||||||
# Make sure all the variant pages have been deleted.
|
# Make sure all the variant pages have been deleted.
|
||||||
assert not len(variants.all())
|
assert not len(variants.all())
|
||||||
assert not len(variants_metadata.all())
|
assert not len(variants_metadata.all())
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_custom_delete_page_view_deletes_variants_of_child_pages(rf, segmented_page, user):
|
||||||
|
"""
|
||||||
|
Regression test for deleting pages that have children with variants
|
||||||
|
"""
|
||||||
|
post_request = rf.post('/')
|
||||||
|
user.is_superuser = True
|
||||||
|
rf.user = user
|
||||||
|
canonical_page = segmented_page.personalisation_metadata.canonical_page
|
||||||
|
# Create a child with a variant
|
||||||
|
child_page = ContentPageFactory(parent=canonical_page, slug='personalised-child')
|
||||||
|
child_page.personalisation_metadata.copy_for_segment(segmented_page.personalisation_metadata.segment)
|
||||||
|
# A ProtectedError would be raised if the bug persists
|
||||||
|
wagtail_hooks.delete_related_variants(
|
||||||
|
post_request, canonical_page
|
||||||
|
)
|
||||||
|
Reference in New Issue
Block a user