From b946db5241b924c72c1079ce30d9b368e2b82f07 Mon Sep 17 00:00:00 2001 From: Florian Apolloner Date: Thu, 27 Sep 2012 15:06:58 +0200 Subject: [PATCH] Fixed #15695 -- Added `ResolverMatch` to the request object. --- django/core/handlers/base.py | 7 ++++--- docs/ref/request-response.txt | 11 +++++++++++ docs/releases/1.5.txt | 3 +++ .../urlpatterns_reverse/namespace_urls.py | 1 + tests/regressiontests/urlpatterns_reverse/tests.py | 5 +++++ tests/regressiontests/urlpatterns_reverse/views.py | 5 +++++ 6 files changed, 29 insertions(+), 3 deletions(-) diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py index 791382bac0..39d109405b 100644 --- a/django/core/handlers/base.py +++ b/django/core/handlers/base.py @@ -95,14 +95,15 @@ class BaseHandler(object): break if response is None: - if hasattr(request, "urlconf"): + if hasattr(request, 'urlconf'): # Reset url resolver with a custom urlconf. urlconf = request.urlconf urlresolvers.set_urlconf(urlconf) resolver = urlresolvers.RegexURLResolver(r'^/', urlconf) - callback, callback_args, callback_kwargs = resolver.resolve( - request.path_info) + resolver_match = resolver.resolve(request.path_info) + callback, callback_args, callback_kwargs = resolver_match + request.resolver_match = resolver_match # Apply view middleware for middleware_method in self._view_middleware: diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt index 21e99de10d..50301b8567 100644 --- a/docs/ref/request-response.txt +++ b/docs/ref/request-response.txt @@ -192,6 +192,17 @@ 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. +.. attribute:: HttpRequest.resolver_match + + .. versionadded:: 1.5 + + An instance of :class:`~django.core.urlresolvers.ResolverMatch` representing + the resolved url. This attribute is only set after url resolving took place, + which means it's available in all views but not in middleware methods which + are executed before url resolving takes place (like ``process_request``, you + can use ``process_view`` instead). + + Methods ------- diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt index 26b6ad1bfa..f1fcd923b1 100644 --- a/docs/releases/1.5.txt +++ b/docs/releases/1.5.txt @@ -127,6 +127,9 @@ Django 1.5 also includes several smaller improvements worth noting: configuration duplication. More information can be found in the :func:`~django.contrib.auth.decorators.login_required` documentation. +* An instance of :class:`~django.core.urlresolvers.ResolverMatch` is stored on + the request as ``resolver_match``. + Backwards incompatible changes in 1.5 ===================================== diff --git a/tests/regressiontests/urlpatterns_reverse/namespace_urls.py b/tests/regressiontests/urlpatterns_reverse/namespace_urls.py index fa892a4346..ab2e77af24 100644 --- a/tests/regressiontests/urlpatterns_reverse/namespace_urls.py +++ b/tests/regressiontests/urlpatterns_reverse/namespace_urls.py @@ -28,6 +28,7 @@ otherobj2 = URLObject('nodefault', 'other-ns2') urlpatterns = patterns('regressiontests.urlpatterns_reverse.views', url(r'^normal/$', 'empty_view', name='normal-view'), url(r'^normal/(?P\d+)/(?P\d+)/$', 'empty_view', name='normal-view'), + url(r'^resolver_match/$', 'pass_resolver_match_view', name='test-resolver-match'), url(r'^\+\\\$\*/$', 'empty_view', name='special-view'), diff --git a/tests/regressiontests/urlpatterns_reverse/tests.py b/tests/regressiontests/urlpatterns_reverse/tests.py index 0ea5ffe380..234897d267 100644 --- a/tests/regressiontests/urlpatterns_reverse/tests.py +++ b/tests/regressiontests/urlpatterns_reverse/tests.py @@ -512,6 +512,11 @@ class ResolverMatchTests(TestCase): self.assertEqual(match[1], args) self.assertEqual(match[2], kwargs) + def test_resolver_match_on_request(self): + response = self.client.get('/resolver_match/') + resolver_match = response.resolver_match + self.assertEqual(resolver_match.url_name, 'test-resolver-match') + class ErroneousViewTests(TestCase): urls = 'regressiontests.urlpatterns_reverse.erroneous_urls' diff --git a/tests/regressiontests/urlpatterns_reverse/views.py b/tests/regressiontests/urlpatterns_reverse/views.py index f631acf3ec..88d169a118 100644 --- a/tests/regressiontests/urlpatterns_reverse/views.py +++ b/tests/regressiontests/urlpatterns_reverse/views.py @@ -19,6 +19,11 @@ def defaults_view(request, arg1, arg2): def erroneous_view(request): import non_existent +def pass_resolver_match_view(request, *args, **kwargs): + response = HttpResponse('') + response.resolver_match = request.resolver_match + return response + uncallable = "Can I be a view? Pleeeease?" class ViewClass(object):