Skip to content

Commit e31e9fb

Browse files
authored
Merge pull request readthedocs#5727 from saadmk11/permanent-redirects
Permanent redirect feature added
2 parents b0379b3 + 6e8836f commit e31e9fb

File tree

5 files changed

+48
-6
lines changed

5 files changed

+48
-6
lines changed

readthedocs/redirects/managers.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@
88

99
class RedirectQuerySet(QuerySet):
1010

11-
def get_redirect_path(self, path, language=None, version_slug=None):
11+
def get_redirect_path_with_status(self, path, language=None, version_slug=None):
1212
for redirect in self.select_related('project'):
1313
new_path = redirect.get_redirect_path(
1414
path=path,
1515
language=language,
1616
version_slug=version_slug,
1717
)
1818
if new_path:
19-
return new_path
20-
return None
19+
return new_path, redirect.http_status
20+
return (None, None)
2121

2222

2323
RedirectManager = Manager.from_queryset(RedirectQuerySet)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.11.20 on 2019-05-23 15:25
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations, models
6+
7+
8+
def change_http_status(apps, schema_editor):
9+
Redirect = apps.get_model('redirects', 'Redirect')
10+
Redirect.objects.update(http_status=302)
11+
12+
13+
class Migration(migrations.Migration):
14+
15+
dependencies = [
16+
('redirects', '0002_add_missing_model_change_migrations'),
17+
]
18+
19+
operations = [
20+
migrations.RunPython(change_http_status),
21+
migrations.AlterField(
22+
model_name='redirect',
23+
name='http_status',
24+
field=models.SmallIntegerField(choices=[(301, '301 - Permanent Redirect'), (302, '302 - Temporary Redirect')], default=302, verbose_name='HTTP Status'),
25+
),
26+
]

readthedocs/redirects/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ class Redirect(models.Model):
8787
http_status = models.SmallIntegerField(
8888
_('HTTP Status'),
8989
choices=HTTP_STATUS_CHOICES,
90-
default=301,
90+
default=302,
9191
)
9292
status = models.BooleanField(choices=STATUS_CHOICES, default=True)
9393

readthedocs/redirects/utils.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import re
1212
from urllib.parse import urlparse, urlunparse
1313

14-
from django.http import HttpResponseRedirect
14+
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
1515

1616
from readthedocs.constants import LANGUAGES_REGEX
1717
from readthedocs.projects.models import Project
@@ -79,7 +79,7 @@ def get_redirect_response(request, full_path):
7979
if not project.single_version:
8080
language, version_slug, path = language_and_version_from_path(path)
8181

82-
path = project.redirects.get_redirect_path(
82+
path, http_status = project.redirects.get_redirect_path_with_status(
8383
path=path, language=language, version_slug=version_slug
8484
)
8585

@@ -91,4 +91,8 @@ def get_redirect_response(request, full_path):
9191
# Re-use the domain and protocol used in the current request.
9292
# Redirects shouldn't change the domain, version or language.
9393
new_path = request.build_absolute_uri(new_path)
94+
95+
if http_status and http_status == 301:
96+
return HttpResponsePermanentRedirect(new_path)
97+
9498
return HttpResponseRedirect(new_path)

readthedocs/rtd_tests/tests/test_redirects.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,18 @@ def test_redirect_htmldir(self):
374374
r['Location'], 'http://pip.readthedocs.org/en/latest/faq/',
375375
)
376376

377+
@override_settings(USE_SUBDOMAIN=True)
378+
def test_redirect_root_with_301_status(self):
379+
Redirect.objects.create(
380+
project=self.pip, redirect_type='prefix',
381+
from_url='/woot/', http_status=301,
382+
)
383+
r = self.client.get('/woot/faq.html', HTTP_HOST='pip.readthedocs.org')
384+
self.assertEqual(r.status_code, 301)
385+
self.assertEqual(
386+
r['Location'], 'http://pip.readthedocs.org/en/latest/faq.html',
387+
)
388+
377389

378390
class CustomRedirectTests(TestCase):
379391

0 commit comments

Comments
 (0)