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.core import serializers
from django.db import models, transaction from django.db import models, transaction
from django.db.models.base import ModelBase from django.db.models.base import ModelBase
from django.db.models.signals import pre_save
from django.db.models import Max from django.db.models import Max
from django.dispatch import receiver
from django.forms import models as model_forms from django.forms import models as model_forms
from django import forms from django import forms
from django import template from django import template
@ -1280,3 +1282,23 @@ class ExternalLinkSearchItem(models.Model):
text = models.TextField(blank=True) text = models.TextField(blank=True)
url = models.CharField(_('URL'), max_length=200, blank=True) url = models.CharField(_('URL'), max_length=200, blank=True)
last_update_timestamp = models.DateTimeField(auto_now=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 = Redirect(old_url='/whatever/', page=page2)
redirect.save() redirect.save()
assert app.get('/whatever/', status=301).location == '/second/' 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/'