general: keep a redirect on slug and parent changes (#20760)

This commit is contained in:
Frédéric Péters 2018-07-12 21:32:59 +02:00
parent 13766c1a28
commit c905276c45
2 changed files with 40 additions and 0 deletions

View File

@ -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()

View File

@ -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/'