فهرست منبع

Merge branch 'ticket15695'

Florian Apolloner 12 سال پیش
والد
کامیت
6a6f589bfe

+ 4 - 3
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:

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

@@ -190,6 +190,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
 -------
 

+ 4 - 1
docs/releases/1.5.txt

@@ -161,7 +161,7 @@ Django 1.5 also includes several smaller improvements worth noting:
   :func:`~django.contrib.auth.decorators.login_required` documentation.
 
 * Django now provides a mod_wsgi :doc:`auth handler
-  </howto/deployment/wsgi/apache-auth>`
+  </howto/deployment/wsgi/apache-auth>`.
 
 * The :meth:`QuerySet.delete() <django.db.models.query.QuerySet.delete>`
   and :meth:`Model.delete() <django.db.models.Model.delete()>` can now take
@@ -169,6 +169,9 @@ Django 1.5 also includes several smaller improvements worth noting:
   objects fetched into memory. See :meth:`QuerySet.delete()
   <django.db.models.query.QuerySet.delete>` for details.
 
+* An instance of :class:`~django.core.urlresolvers.ResolverMatch` is stored on
+  the request as ``resolver_match``.
+
 Backwards incompatible changes in 1.5
 =====================================
 

+ 1 - 0
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<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'),
 

+ 5 - 0
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'
 

+ 5 - 0
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):