Explorar o código

Fixed #14200 -- Added a fallback if HttpRequest.urlconf is None.

Made BaseHandler fall back to settings.ROOT_URLCONF if
HttpRequest.urlconf is set to None, rather than raising
ImproperlyConfigured.
Marten Kenbeek %!s(int64=9) %!d(string=hai) anos
pai
achega
738c0de300

+ 2 - 2
django/core/handlers/base.py

@@ -112,7 +112,7 @@ class BaseHandler(object):
         # resolver is set
         urlconf = settings.ROOT_URLCONF
         urlresolvers.set_urlconf(urlconf)
-        resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
+        resolver = urlresolvers.get_resolver(urlconf)
         # Use a flag to check if the response was rendered to prevent
         # multiple renderings or to force rendering if necessary.
         response_is_rendered = False
@@ -129,7 +129,7 @@ class BaseHandler(object):
                     # Reset url resolver with a custom urlconf.
                     urlconf = request.urlconf
                     urlresolvers.set_urlconf(urlconf)
-                    resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
+                    resolver = urlresolvers.get_resolver(urlconf)
 
                 resolver_match = resolver.resolve(request.path_info)
                 callback, callback_args, callback_kwargs = resolver_match

+ 8 - 0
docs/ref/request-response.txt

@@ -184,6 +184,14 @@ All attributes should be considered read-only, unless stated otherwise below.
     URLconf for the current request, overriding the :setting:`ROOT_URLCONF`
     setting. See :ref:`how-django-processes-a-request` for details.
 
+    ``urlconf`` can be set to ``None`` to revert any changes made by previous
+    middleware and return to using the :setting:`ROOT_URLCONF`.
+
+    .. versionchanged:: 1.9
+
+        Setting ``urlconf=None`` raised
+        :exc:`~django.core.exceptions.ImproperlyConfigured` in older versions.
+
 .. attribute:: HttpRequest.resolver_match
 
     An instance of :class:`~django.core.urlresolvers.ResolverMatch` representing

+ 4 - 0
docs/releases/1.9.txt

@@ -435,6 +435,10 @@ Requests and Responses
   :class:`~django.template.response.TemplateResponse`, commonly used with
   class-based views.
 
+* Request middleware can now set :attr:`HttpRequest.urlconf
+  <django.http.HttpRequest.urlconf>` to ``None`` to revert any changes made
+  by previous middleware and return to using the :setting:`ROOT_URLCONF`.
+
 Tests
 ^^^^^
 

+ 3 - 3
docs/topics/http/urls.txt

@@ -40,9 +40,9 @@ algorithm the system follows to determine which Python code to execute:
 
 1. Django determines the root URLconf module to use. Ordinarily,
    this is the value of the :setting:`ROOT_URLCONF` setting, but if the incoming
-   ``HttpRequest`` object has an attribute called ``urlconf`` (set by
-   middleware :ref:`request processing <request-middleware>`), its value
-   will be used in place of the :setting:`ROOT_URLCONF` setting.
+   ``HttpRequest`` object has a :attr:`~django.http.HttpRequest.urlconf`
+   attribute (set by middleware :ref:`request processing <request-middleware>`),
+   its value will be used in place of the :setting:`ROOT_URLCONF` setting.
 
 2. Django loads that Python module and looks for the variable
    ``urlpatterns``. This should be a Python list of :func:`django.conf.urls.url`

+ 11 - 1
tests/urlpatterns_reverse/tests.py

@@ -700,7 +700,17 @@ class RequestURLconfTests(SimpleTestCase):
         ]
     )
     def test_urlconf_overridden_with_null(self):
-        self.assertRaises(ImproperlyConfigured, self.client.get, '/test/me/')
+        """
+        Overriding request.urlconf with None will fall back to the default
+        URLconf.
+        """
+        response = self.client.get('/test/me/')
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response.content, b'outer:/test/me/,inner:/inner_urlconf/second_test/')
+        response = self.client.get('/inner_urlconf/second_test/')
+        self.assertEqual(response.status_code, 200)
+        response = self.client.get('/second_test/')
+        self.assertEqual(response.status_code, 404)
 
     @override_settings(
         MIDDLEWARE_CLASSES=[