summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBerker Peksag <berker.peksag@gmail.com>2014-11-21 18:55:58 +0200
committerTim Graham <timograham@gmail.com>2014-11-25 09:22:18 -0500
commit9a30acad8a1996c914351bad981d937de4db29a4 (patch)
tree15f6d9a64f5323121a7a532b3330a82f7dc5d104
parentd43dd03ca3afecc27f43fbc932f239470a2f07db (diff)
Fixed #21587 -- Added a warning for changing default of RedirectView.permanent.
-rw-r--r--django/views/generic/base.py18
-rw-r--r--docs/internals/deprecation.txt4
-rw-r--r--docs/ref/class-based-views/base.txt5
-rw-r--r--docs/releases/1.8.txt7
-rw-r--r--tests/generic_views/test_base.py69
-rw-r--r--tests/test_client/tests.py45
-rw-r--r--tests/urlpatterns_reverse/tests.py8
7 files changed, 135 insertions, 21 deletions
diff --git a/django/views/generic/base.py b/django/views/generic/base.py
index d66f45b599..594122ef77 100644
--- a/django/views/generic/base.py
+++ b/django/views/generic/base.py
@@ -1,6 +1,7 @@
from __future__ import unicode_literals
import logging
+import warnings
from functools import update_wrapper
from django import http
@@ -8,8 +9,10 @@ from django.core.exceptions import ImproperlyConfigured
from django.core.urlresolvers import reverse, NoReverseMatch
from django.template.response import TemplateResponse
from django.utils.decorators import classonlymethod
+from django.utils.deprecation import RemovedInDjango19Warning
from django.utils import six
+_sentinel = object()
logger = logging.getLogger('django.request')
@@ -48,7 +51,6 @@ class View(object):
"""
Main entry point for a request-response process.
"""
- # sanitize keyword arguments
for key in initkwargs:
if key in cls.http_method_names:
raise TypeError("You tried to pass in the %s method name as a "
@@ -159,11 +161,23 @@ class RedirectView(View):
"""
A view that provides a redirect on any GET request.
"""
- permanent = True
+ permanent = _sentinel
url = None
pattern_name = None
query_string = False
+ def __init__(self, *args, **kwargs):
+ if 'permanent' not in kwargs and self.permanent is _sentinel:
+ warnings.warn(
+ "Default value of 'RedirectView.permanent' will change "
+ "from True to False in Django 1.9. Set an explicit value "
+ "to silence this warning.",
+ RemovedInDjango19Warning,
+ stacklevel=3
+ )
+ self.permanent = True
+ super(RedirectView, self).__init__(*args, **kwargs)
+
def get_redirect_url(self, *args, **kwargs):
"""
Return the URL redirect to. Keyword arguments from the
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt
index 1f4aca4cf3..3750d469dd 100644
--- a/docs/internals/deprecation.txt
+++ b/docs/internals/deprecation.txt
@@ -214,6 +214,10 @@ details on these changes.
* The `cache_choices` option to :class:`~django.forms.ModelChoiceField` and
:class:`~django.forms.ModelMultipleChoiceField` will be removed.
+* The default value of the
+ :attr:`RedirectView.permanent <django.views.generic.base.RedirectView.permanent>`
+ attribute will change from ``True`` to ``False``.
+
.. _deprecation-removed-in-1.8:
1.8
diff --git a/docs/ref/class-based-views/base.txt b/docs/ref/class-based-views/base.txt
index e6c35fffd0..523b39d0e2 100644
--- a/docs/ref/class-based-views/base.txt
+++ b/docs/ref/class-based-views/base.txt
@@ -222,6 +222,11 @@ RedirectView
status code 301. If ``False``, then the redirect will use status code
302. By default, ``permanent`` is ``True``.
+ .. deprecated:: 1.8
+
+ The default value of the ``permanent`` attribute will change from
+ ``True`` to ``False`` in Django 1.9.
+
.. attribute:: query_string
Whether to pass along the GET query string to the new location. If
diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt
index 7064891312..ba0b0cfa2b 100644
--- a/docs/releases/1.8.txt
+++ b/docs/releases/1.8.txt
@@ -1097,6 +1097,13 @@ deprecated: you should rename your ``qn`` arguments to ``compiler``, and call
``compiler.quote_name_unless_alias(...)`` where you previously called
``qn(...)``.
+Default value of ``RedirectView.permanent``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The default value of the
+:attr:`RedirectView.permanent <django.views.generic.base.RedirectView.permanent>`
+attribute will change from ``True`` to ``False`` in Django 1.9.
+
.. removed-features-1.8:
Features removed in 1.8
diff --git a/tests/generic_views/test_base.py b/tests/generic_views/test_base.py
index 29e225088d..1a1236a084 100644
--- a/tests/generic_views/test_base.py
+++ b/tests/generic_views/test_base.py
@@ -2,10 +2,14 @@ from __future__ import unicode_literals
import time
import unittest
+import warnings
from django.core.exceptions import ImproperlyConfigured
from django.http import HttpResponse
+from django.utils import six
+from django.utils.deprecation import RemovedInDjango19Warning
from django.test import TestCase, RequestFactory, override_settings
+from django.test.utils import IgnoreDeprecationWarningsMixin
from django.views.generic import View, TemplateView, RedirectView
from . import views
@@ -328,7 +332,7 @@ class TemplateViewTest(TestCase):
@override_settings(ROOT_URLCONF='generic_views.urls')
-class RedirectViewTest(TestCase):
+class RedirectViewTest(IgnoreDeprecationWarningsMixin, TestCase):
rf = RequestFactory()
@@ -440,6 +444,69 @@ class RedirectViewTest(TestCase):
self.assertEqual(response.status_code, 410)
+@override_settings(ROOT_URLCONF='generic_views.urls')
+class RedirectViewDeprecationTest(TestCase):
+
+ rf = RequestFactory()
+
+ def test_deprecation_warning_init(self):
+ with warnings.catch_warnings(record=True) as warns:
+ warnings.simplefilter('always')
+
+ view = RedirectView()
+ response = view.dispatch(self.rf.head('/python/'))
+
+ self.assertEqual(response.status_code, 410)
+ self.assertEqual(len(warns), 1)
+ self.assertIs(warns[0].category, RemovedInDjango19Warning)
+ self.assertEqual(
+ six.text_type(warns[0].message),
+ "Default value of 'RedirectView.permanent' will change "
+ "from True to False in Django 1.9. Set an explicit value "
+ "to silence this warning.",
+ )
+
+ def test_deprecation_warning_raised_when_permanent_not_passed(self):
+ with warnings.catch_warnings(record=True) as warns:
+ warnings.simplefilter('always')
+
+ view_function = RedirectView.as_view(url='/bbb/')
+ request = self.rf.request(PATH_INFO='/aaa/')
+ view_function(request)
+
+ self.assertEqual(len(warns), 1)
+ self.assertIs(warns[0].category, RemovedInDjango19Warning)
+ self.assertEqual(
+ six.text_type(warns[0].message),
+ "Default value of 'RedirectView.permanent' will change "
+ "from True to False in Django 1.9. Set an explicit value "
+ "to silence this warning.",
+ )
+
+ def test_no_deprecation_warning_when_permanent_passed(self):
+ with warnings.catch_warnings(record=True) as warns:
+ warnings.simplefilter('always')
+
+ view_function = RedirectView.as_view(url='/bar/', permanent=False)
+ request = self.rf.request(PATH_INFO='/foo/')
+ view_function(request)
+
+ self.assertEqual(len(warns), 0)
+
+ def test_no_deprecation_warning_with_custom_redirectview(self):
+ class CustomRedirectView(RedirectView):
+ permanent = False
+
+ with warnings.catch_warnings(record=True) as warns:
+ warnings.simplefilter('always')
+
+ view_function = CustomRedirectView.as_view(url='/eggs/')
+ request = self.rf.request(PATH_INFO='/spam/')
+ view_function(request)
+
+ self.assertEqual(len(warns), 0)
+
+
class GetContextDataTest(unittest.TestCase):
def test_get_context_data_super(self):
diff --git a/tests/test_client/tests.py b/tests/test_client/tests.py
index cf96b89a62..4ed7c6c1f8 100644
--- a/tests/test_client/tests.py
+++ b/tests/test_client/tests.py
@@ -22,8 +22,11 @@ rather than the HTML rendered to the end-user.
"""
from __future__ import unicode_literals
+import warnings
+
from django.core import mail
from django.http import HttpResponse
+from django.utils.deprecation import RemovedInDjango19Warning
from django.test import Client, TestCase, RequestFactory
from django.test import override_settings
@@ -174,14 +177,18 @@ class ClientTest(TestCase):
def test_permanent_redirect(self):
"GET a URL that redirects permanently elsewhere"
- response = self.client.get('/permanent_redirect_view/')
- # Check that the response was a 301 (permanent redirect)
- self.assertRedirects(response, 'http://testserver/get_view/', status_code=301)
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", RemovedInDjango19Warning)
+ response = self.client.get('/permanent_redirect_view/')
+ # Check that the response was a 301 (permanent redirect)
+ self.assertRedirects(response, 'http://testserver/get_view/', status_code=301)
- client_providing_host = Client(HTTP_HOST='django.testserver')
- response = client_providing_host.get('/permanent_redirect_view/')
- # Check that the response was a 301 (permanent redirect) with absolute URI
- self.assertRedirects(response, 'http://django.testserver/get_view/', status_code=301)
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", RemovedInDjango19Warning)
+ client_providing_host = Client(HTTP_HOST='django.testserver')
+ response = client_providing_host.get('/permanent_redirect_view/')
+ # Check that the response was a 301 (permanent redirect) with absolute URI
+ self.assertRedirects(response, 'http://django.testserver/get_view/', status_code=301)
def test_temporary_redirect(self):
"GET a URL that does a non-permanent redirect"
@@ -191,26 +198,34 @@ class ClientTest(TestCase):
def test_redirect_to_strange_location(self):
"GET a URL that redirects to a non-200 page"
- response = self.client.get('/double_redirect_view/')
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", RemovedInDjango19Warning)
+ response = self.client.get('/double_redirect_view/')
- # Check that the response was a 302, and that
- # the attempt to get the redirection location returned 301 when retrieved
- self.assertRedirects(response, 'http://testserver/permanent_redirect_view/', target_status_code=301)
+ # Check that the response was a 302, and that
+ # the attempt to get the redirection location returned 301 when retrieved
+ self.assertRedirects(response, 'http://testserver/permanent_redirect_view/', target_status_code=301)
def test_follow_redirect(self):
"A URL that redirects can be followed to termination."
- response = self.client.get('/double_redirect_view/', follow=True)
- self.assertRedirects(response, 'http://testserver/get_view/', status_code=302, target_status_code=200)
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", RemovedInDjango19Warning)
+ response = self.client.get('/double_redirect_view/', follow=True)
+ self.assertRedirects(response, 'http://testserver/get_view/', status_code=302, target_status_code=200)
self.assertEqual(len(response.redirect_chain), 2)
def test_redirect_http(self):
"GET a URL that redirects to an http URI"
- response = self.client.get('/http_redirect_view/', follow=True)
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", RemovedInDjango19Warning)
+ response = self.client.get('/http_redirect_view/', follow=True)
self.assertFalse(response.test_was_secure_request)
def test_redirect_https(self):
"GET a URL that redirects to an https URI"
- response = self.client.get('/https_redirect_view/', follow=True)
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", RemovedInDjango19Warning)
+ response = self.client.get('/https_redirect_view/', follow=True)
self.assertTrue(response.test_was_secure_request)
def test_notfound_response(self):
diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py
index 18299fe733..0c4e08369e 100644
--- a/tests/urlpatterns_reverse/tests.py
+++ b/tests/urlpatterns_reverse/tests.py
@@ -18,7 +18,7 @@ from django.http import HttpRequest, HttpResponseRedirect, HttpResponsePermanent
from django.shortcuts import redirect
from django.test import TestCase, override_settings
from django.utils import six
-from django.utils.deprecation import RemovedInDjango20Warning
+from django.utils.deprecation import RemovedInDjango19Warning, RemovedInDjango20Warning
from admin_scripts.tests import AdminScriptTestCase
@@ -309,8 +309,10 @@ class ResolverTests(unittest.TestCase):
class ReverseLazyTest(TestCase):
def test_redirect_with_lazy_reverse(self):
- response = self.client.get('/redirect/')
- self.assertRedirects(response, "/redirected_to/", status_code=301)
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", RemovedInDjango19Warning)
+ response = self.client.get('/redirect/')
+ self.assertRedirects(response, "/redirected_to/", status_code=301)
def test_user_permission_with_lazy_reverse(self):
User.objects.create_user('alfred', 'alfred@example.com', password='testpw')