Projet

Général

Profil

0001-general-use-a-model-to-look-for-redirection-before-e.patch

Frédéric Péters, 13 juillet 2018 08:46

Télécharger (5,39 ko)

Voir les différences:

Subject: [PATCH 1/2] general: use a model to look for redirection before
 emitting a 404 (#20760)

 combo/data/migrations/0034_redirect.py | 28 ++++++++++++++++++++++++++
 combo/data/models.py                   |  9 +++++++++
 combo/public/views.py                  | 17 ++++++++--------
 tests/test_public.py                   | 27 ++++++++++++++++++++++++-
 4 files changed, 72 insertions(+), 9 deletions(-)
 create mode 100644 combo/data/migrations/0034_redirect.py
combo/data/migrations/0034_redirect.py
1
# -*- coding: utf-8 -*-
2
# Generated by Django 1.11.12 on 2018-07-13 06:40
3
from __future__ import unicode_literals
4

  
5
from django.db import migrations, models
6
import django.db.models.deletion
7

  
8

  
9
class Migration(migrations.Migration):
10

  
11
    dependencies = [
12
        ('data', '0033_auto_20180401_1300'),
13
    ]
14

  
15
    operations = [
16
        migrations.CreateModel(
17
            name='Redirect',
18
            fields=[
19
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20
                ('old_url', models.CharField(max_length=512)),
21
                ('creation_timestamp', models.DateTimeField(auto_now_add=True)),
22
                ('page', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='data.Page')),
23
            ],
24
            options={
25
                'ordering': ('creation_timestamp',),
26
            },
27
        ),
28
    ]
combo/data/models.py
409 409
        return page
410 410

  
411 411

  
412
class Redirect(models.Model):
413
    old_url = models.CharField(max_length=512)
414
    page = models.ForeignKey(Page)
415
    creation_timestamp = models.DateTimeField(auto_now_add=True)
416

  
417
    class Meta:
418
        ordering = ('creation_timestamp',)
419

  
420

  
412 421
class CellMeta(MediaDefiningClass, ModelBase):
413 422
    pass
414 423

  
combo/public/views.py
44 44
else:
45 45
    get_idps = lambda: []
46 46

  
47
from combo.data.models import CellBase, PostException, Page, ParentContentCell, TextCell, PageSnapshot
47
from combo.data.models import (CellBase, PostException, Page, Redirect,
48
        ParentContentCell, TextCell, PageSnapshot)
48 49
from combo.profile.models import Profile
49 50
from combo.apps.search.models import SearchCell
50 51
from combo import utils
......
353 354
    except Page.DoesNotExist:
354 355
        if Page.objects.count() == 0 and parts == ['index']:
355 356
            return empty_site(request)
356
        else:
357
            if not url.endswith('/') and settings.APPEND_SLASH:
358
                # this is useful to allow /login, /manage, and other non-page
359
                # URLs to work.
360
                return HttpResponsePermanentRedirect(url + '/')
361
            raise Http404()
357
        page = None
362 358

  
363
    if page.get_online_url() != url:
359
    if page is None or page.get_online_url() != url:
364 360
        if not url.endswith('/') and settings.APPEND_SLASH:
361
            # this is useful to allow /login, /manage, and other non-page
362
            # URLs to work.
365 363
            return HttpResponsePermanentRedirect(url + '/')
364
        redirect = Redirect.objects.filter(old_url=url).last()
365
        if redirect:
366
            return HttpResponsePermanentRedirect(redirect.page.get_online_url())
366 367
        raise Http404()
367 368

  
368 369
    return publish_page(request, page)
tests/test_public.py
16 16

  
17 17
from combo.wsgi import application
18 18
from combo.data.models import (Page, CellBase, TextCell, ParentContentCell,
19
        FeedCell, LinkCell, ConfigJsonCell)
19
        FeedCell, LinkCell, ConfigJsonCell, Redirect)
20 20
from combo.apps.family.models import FamilyInfosCell
21 21

  
22 22
pytestmark = pytest.mark.django_db
......
584 584

  
585 585
            resp = app.get('/foo/', status=200)
586 586
            assert resp.body.count('data-ajax-cell-must-load="true"') == 1
587

  
588
def test_redirects(app):
589
    Redirect.objects.all().delete()
590
    Page.objects.all().delete()
591
    page = Page(title='Home', slug='index', template_name='standard')
592
    page.save()
593

  
594
    page2 = Page(title='Second', slug='second', template_name='standard')
595
    page2.save()
596

  
597
    page3 = Page(title='Third', slug='third', template_name='standard', parent=page2)
598
    page3.save()
599

  
600
    app.get('/whatever/', status=404)
601

  
602
    redirect = Redirect(old_url='/whatever/', page=page3)
603
    redirect.save()
604

  
605
    assert app.get('/whatever/', status=301).location == '/second/third/'
606
    assert app.get('/whatever', status=301).location == '/whatever/'
607

  
608
    # check the most recent redirect is called
609
    redirect = Redirect(old_url='/whatever/', page=page2)
610
    redirect.save()
611
    assert app.get('/whatever/', status=301).location == '/second/'
587
-