general: use a model to look for redirection before emitting a 404 (#20760)
This commit is contained in:
parent
e985190952
commit
13766c1a28
|
@ -0,0 +1,28 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.12 on 2018-07-13 06:40
|
||||
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)),
|
||||
('creation_timestamp', models.DateTimeField(auto_now_add=True)),
|
||||
('page', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='data.Page')),
|
||||
],
|
||||
options={
|
||||
'ordering': ('creation_timestamp',),
|
||||
},
|
||||
),
|
||||
]
|
|
@ -409,6 +409,15 @@ class PageSnapshot(models.Model):
|
|||
return page
|
||||
|
||||
|
||||
class Redirect(models.Model):
|
||||
old_url = models.CharField(max_length=512)
|
||||
page = models.ForeignKey(Page)
|
||||
creation_timestamp = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ('creation_timestamp',)
|
||||
|
||||
|
||||
class CellMeta(MediaDefiningClass, ModelBase):
|
||||
pass
|
||||
|
||||
|
|
|
@ -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,16 @@ 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 + '/')
|
||||
redirect = Redirect.objects.filter(old_url=url).last()
|
||||
if redirect:
|
||||
return HttpResponsePermanentRedirect(redirect.page.get_online_url())
|
||||
raise Http404()
|
||||
|
||||
return publish_page(request, page)
|
||||
|
|
|
@ -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,28 @@ 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):
|
||||
Redirect.objects.all().delete()
|
||||
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/'
|
||||
|
||||
# check the most recent redirect is called
|
||||
redirect = Redirect(old_url='/whatever/', page=page2)
|
||||
redirect.save()
|
||||
assert app.get('/whatever/', status=301).location == '/second/'
|
||||
|
|
Loading…
Reference in New Issue