From c905276c4570c8da4b38d5eab474bde3d7764adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Thu, 12 Jul 2018 21:32:59 +0200 Subject: [PATCH] general: keep a redirect on slug and parent changes (#20760) --- combo/data/models.py | 22 ++++++++++++++++++++++ tests/test_public.py | 18 ++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/combo/data/models.py b/combo/data/models.py index 0f937dba..825ab3bc 100644 --- a/combo/data/models.py +++ b/combo/data/models.py @@ -34,7 +34,9 @@ from django.core.exceptions import ObjectDoesNotExist, ValidationError, Permissi from django.core import serializers from django.db import models, transaction from django.db.models.base import ModelBase +from django.db.models.signals import pre_save from django.db.models import Max +from django.dispatch import receiver from django.forms import models as model_forms from django import forms from django import template @@ -1280,3 +1282,23 @@ class ExternalLinkSearchItem(models.Model): text = models.TextField(blank=True) url = models.CharField(_('URL'), max_length=200, blank=True) last_update_timestamp = models.DateTimeField(auto_now=True) + + +@receiver(pre_save, sender=Page) +def create_redirects(sender, instance, raw, **kwargs): + if raw or not instance.id or instance.snapshot_id: + return + try: + old_page = Page.objects.get(id=instance.id) + except Page.DoesNotExist: + return + if old_page.slug == instance.slug and old_page.parent_id == instance.parent_id: + return + affected_pages = level_pages = [old_page] + while True: + level_pages = Page.objects.filter(parent_id__in=[x.id for x in level_pages]).select_related('parent') + if len(level_pages) == 0: + break + affected_pages.extend(level_pages) + for page in affected_pages: + Redirect(page=page, old_url=page.get_online_url()).save() diff --git a/tests/test_public.py b/tests/test_public.py index 7c3ec9cd..1a57fd5d 100644 --- a/tests/test_public.py +++ b/tests/test_public.py @@ -609,3 +609,21 @@ def test_redirects(app): redirect = Redirect(old_url='/whatever/', page=page2) redirect.save() assert app.get('/whatever/', status=301).location == '/second/' + + # rename page + page3.slug = 'third2' + page3.save() + assert app.get('/second/third2/', status=200) + assert app.get('/second/third/', status=301).location == '/second/third2/' + + page2.slug = 'second2' + page2.save() + assert app.get('/second/third/', status=301).location == '/second2/third2/' + assert app.get('/second/third2/', status=301).location == '/second2/third2/' + assert app.get('/second/', status=301).location == '/second2/' + + # change parent + page3.parent = None + page3.save() + assert app.get('/second/third/', status=301).location == '/third2/' + assert app.get('/second2/third2/', status=301).location == '/third2/'