Commit 738c0de3 authored by Marten Kenbeek's avatar Marten Kenbeek Committed by Tim Graham
Browse files

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.
parent 74402a5b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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=[