Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed #15695 -- Added ResolverMatch to the request object. #399

Merged
merged 1 commit into from Sep 29, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 4 additions & 3 deletions django/core/handlers/base.py
Expand Up @@ -95,14 +95,15 @@ def get_response(self, request):
break break


if response is None: if response is None:
if hasattr(request, "urlconf"): if hasattr(request, 'urlconf'):
# Reset url resolver with a custom urlconf. # Reset url resolver with a custom urlconf.
urlconf = request.urlconf urlconf = request.urlconf
urlresolvers.set_urlconf(urlconf) urlresolvers.set_urlconf(urlconf)
resolver = urlresolvers.RegexURLResolver(r'^/', urlconf) resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)


callback, callback_args, callback_kwargs = resolver.resolve( resolver_match = resolver.resolve(request.path_info)
request.path_info) callback, callback_args, callback_kwargs = resolver_match
request.resolver_match = resolver_match


# Apply view middleware # Apply view middleware
for middleware_method in self._view_middleware: for middleware_method in self._view_middleware:
Expand Down
11 changes: 11 additions & 0 deletions docs/ref/request-response.txt
Expand Up @@ -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` URLconf for the current request, overriding the :setting:`ROOT_URLCONF`
setting. See :ref:`how-django-processes-a-request` for details. 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 Methods
------- -------


Expand Down
3 changes: 3 additions & 0 deletions docs/releases/1.5.txt
Expand Up @@ -127,6 +127,9 @@ Django 1.5 also includes several smaller improvements worth noting:
configuration duplication. More information can be found in the configuration duplication. More information can be found in the
:func:`~django.contrib.auth.decorators.login_required` documentation. :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 Backwards incompatible changes in 1.5
===================================== =====================================


Expand Down
Expand Up @@ -28,6 +28,7 @@ def urls(self):
urlpatterns = patterns('regressiontests.urlpatterns_reverse.views', urlpatterns = patterns('regressiontests.urlpatterns_reverse.views',
url(r'^normal/$', 'empty_view', name='normal-view'), url(r'^normal/$', 'empty_view', name='normal-view'),
url(r'^normal/(?P<arg1>\d+)/(?P<arg2>\d+)/$', 'empty_view', name='normal-view'), url(r'^normal/(?P<arg1>\d+)/(?P<arg2>\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'), url(r'^\+\\\$\*/$', 'empty_view', name='special-view'),


Expand Down
5 changes: 5 additions & 0 deletions tests/regressiontests/urlpatterns_reverse/tests.py
Expand Up @@ -512,6 +512,11 @@ def test_urlpattern_resolve(self):
self.assertEqual(match[1], args) self.assertEqual(match[1], args)
self.assertEqual(match[2], kwargs) 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): class ErroneousViewTests(TestCase):
urls = 'regressiontests.urlpatterns_reverse.erroneous_urls' urls = 'regressiontests.urlpatterns_reverse.erroneous_urls'


Expand Down
5 changes: 5 additions & 0 deletions tests/regressiontests/urlpatterns_reverse/views.py
Expand Up @@ -19,6 +19,11 @@ def defaults_view(request, arg1, arg2):
def erroneous_view(request): def erroneous_view(request):
import non_existent 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?" uncallable = "Can I be a view? Pleeeease?"


class ViewClass(object): class ViewClass(object):
Expand Down