From 6e0700dcf105facc7753d41c4088f1933138581b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Thu, 12 Jul 2018 20:45:37 +0200 Subject: [PATCH 1/2] general: add model to store redirections (#20760) --- combo/data/migrations/0034_redirect.py | 24 ++++++++++++++++++++++++ combo/data/models.py | 5 +++++ combo/public/views.py | 20 ++++++++++++-------- tests/test_public.py | 21 ++++++++++++++++++++- 4 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 combo/data/migrations/0034_redirect.py diff --git a/combo/data/migrations/0034_redirect.py b/combo/data/migrations/0034_redirect.py new file mode 100644 index 0000000..0ba1582 --- /dev/null +++ b/combo/data/migrations/0034_redirect.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.12 on 2018-07-12 18:44 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('data', '0033_auto_20180401_1300'), + ] + + operations = [ + migrations.CreateModel( + name='Redirect', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('old_url', models.CharField(max_length=512)), + ('page', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='data.Page')), + ], + ), + ] diff --git a/combo/data/models.py b/combo/data/models.py index 3885ab3..5714ae7 100644 --- a/combo/data/models.py +++ b/combo/data/models.py @@ -409,6 +409,11 @@ class PageSnapshot(models.Model): return page +class Redirect(models.Model): + old_url = models.CharField(max_length=512) + page = models.ForeignKey(Page) + + class CellMeta(MediaDefiningClass, ModelBase): pass diff --git a/combo/public/views.py b/combo/public/views.py index 6e5e153..1cfcbe7 100644 --- a/combo/public/views.py +++ b/combo/public/views.py @@ -44,7 +44,8 @@ if 'mellon' in settings.INSTALLED_APPS: else: get_idps = lambda: [] -from combo.data.models import CellBase, PostException, Page, ParentContentCell, TextCell, PageSnapshot +from combo.data.models import (CellBase, PostException, Page, Redirect, + ParentContentCell, TextCell, PageSnapshot) from combo.profile.models import Profile from combo.apps.search.models import SearchCell from combo import utils @@ -353,16 +354,19 @@ def page(request): except Page.DoesNotExist: if Page.objects.count() == 0 and parts == ['index']: return empty_site(request) - else: - if not url.endswith('/') and settings.APPEND_SLASH: - # this is useful to allow /login, /manage, and other non-page - # URLs to work. - return HttpResponsePermanentRedirect(url + '/') - raise Http404() + page = None - if page.get_online_url() != url: + if page is None or page.get_online_url() != url: if not url.endswith('/') and settings.APPEND_SLASH: + # this is useful to allow /login, /manage, and other non-page + # URLs to work. return HttpResponsePermanentRedirect(url + '/') + try: + redirect = Redirect.objects.get(old_url=url) + except Redirect.DoesNotExist: + pass + else: + return HttpResponsePermanentRedirect(redirect.page.get_online_url()) raise Http404() return publish_page(request, page) diff --git a/tests/test_public.py b/tests/test_public.py index 57cb638..2312aa5 100644 --- a/tests/test_public.py +++ b/tests/test_public.py @@ -16,7 +16,7 @@ from django.test.utils import CaptureQueriesContext from combo.wsgi import application from combo.data.models import (Page, CellBase, TextCell, ParentContentCell, - FeedCell, LinkCell, ConfigJsonCell) + FeedCell, LinkCell, ConfigJsonCell, Redirect) from combo.apps.family.models import FamilyInfosCell pytestmark = pytest.mark.django_db @@ -584,3 +584,22 @@ def test_synchronous_placeholder(app): resp = app.get('/foo/', status=200) assert resp.body.count('data-ajax-cell-must-load="true"') == 1 + +def test_redirects(app): + Page.objects.all().delete() + page = Page(title='Home', slug='index', template_name='standard') + page.save() + + page2 = Page(title='Second', slug='second', template_name='standard') + page2.save() + + page3 = Page(title='Third', slug='third', template_name='standard', parent=page2) + page3.save() + + app.get('/whatever/', status=404) + + redirect = Redirect(old_url='/whatever/', page=page3) + redirect.save() + + assert app.get('/whatever/', status=301).location == '/second/third/' + assert app.get('/whatever', status=301).location == '/whatever/' -- 2.18.0