Ticket #5034: request_aware_reversing.2.diff
File request_aware_reversing.2.diff, 11.1 KB (added by , 17 years ago) |
---|
-
django/core/urlresolvers.py
7 7 (view_function, function_args, function_kwargs) 8 8 """ 9 9 10 from django.http import Http404 10 from django.http import Http404, HttpRequest 11 11 from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist 12 12 from django.utils.encoding import iri_to_uri, force_unicode, smart_str 13 13 from django.utils.functional import memoize 14 14 import re 15 import types 15 16 16 17 try: 17 18 reversed … … 201 202 class RegexURLResolver(object): 202 203 def __init__(self, regex, urlconf_name, default_kwargs=None): 203 204 # regex is a string representing a regular expression. 204 # urlconf_name is a string representing the module containing urlconfs. 205 # urlconf_name could either be a string representing the module 206 # containing urlconfs or the module itself. 205 207 self.regex = re.compile(regex, re.UNICODE) 206 self.urlconf_name = urlconf_name 208 if isinstance(urlconf_name, types.ModuleType): 209 self._urlconf_module = urlconf_name 210 self.urlconf_name = urlconf_name.__name__ 211 else: 212 self.urlconf_name = urlconf_name 207 213 self.callback = None 208 214 self.default_kwargs = default_kwargs or {} 209 215 self._reverse_dict = {} … … 294 300 def reverse(viewname, urlconf=None, args=None, kwargs=None): 295 301 args = args or [] 296 302 kwargs = kwargs or {} 303 # urlconf could also be an HttpRequest (abstracting the need for high-level 304 # code to check for a request.urlconf) 305 if urlconf is not None and isinstance(urlconf, HttpRequest): 306 urlconf = getattr(urlconf, 'urlconf', None) 297 307 return iri_to_uri(u'/' + get_resolver(urlconf).reverse(viewname, *args, **kwargs)) 298 -
django/contrib/sitemaps/views.py
1 1 from django.http import HttpResponse, Http404 2 2 from django.template import loader 3 3 from django.contrib.sites.models import Site 4 from django.core import urlresolvers4 from django.core.urlresolvers import reverse 5 5 from django.utils.encoding import smart_str 6 6 7 7 def index(request, sitemaps): … … 9 9 sites = [] 10 10 protocol = request.is_secure() and 'https' or 'http' 11 11 for section in sitemaps.keys(): 12 sitemap_url = urlresolvers.reverse('django.contrib.sitemaps.views.sitemap', kwargs={'section': section}) 12 sitemap_url = reverse('django.contrib.sitemaps.views.sitemap', 13 urlconf=request, kwargs={'section': section}) 13 14 sites.append('%s://%s%s' % (protocol, current_site.domain, sitemap_url)) 14 15 xml = loader.render_to_string('sitemap_index.xml', {'sitemaps': sites}) 15 16 return HttpResponse(xml, mimetype='application/xml') -
django/template/defaulttags.py
8 8 except NameError: 9 9 from django.utils.itercompat import reversed # Python 2.3 fallback 10 10 11 from django.template import Node, NodeList, Template, Context, Variable11 from django.template import Node, NodeList, Template, Context, RequestContext, Variable 12 12 from django.template import TemplateSyntaxError, VariableDoesNotExist, BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END 13 13 from django.template import get_library, Library, InvalidTemplateLibrary 14 14 from django.conf import settings … … 359 359 args = [arg.resolve(context) for arg in self.args] 360 360 kwargs = dict([(smart_str(k,'ascii'), v.resolve(context)) 361 361 for k, v in self.kwargs.items()]) 362 if isinstance(context, RequestContext): 363 urlconf = context.request 364 else: 365 urlconf = None 362 366 try: 363 return reverse(self.view_name, args=args, kwargs=kwargs)367 return reverse(self.view_name, urlconf, args=args, kwargs=kwargs) 364 368 except NoReverseMatch: 365 369 try: 366 370 project_name = settings.SETTINGS_MODULE.split('.')[0] 367 return reverse(project_name + '.' + self.view_name, 371 return reverse(project_name + '.' + self.view_name, urlconf, 368 372 args=args, kwargs=kwargs) 369 373 except NoReverseMatch: 370 374 return '' -
django/template/context.py
95 95 """ 96 96 def __init__(self, request, dict=None, processors=None): 97 97 Context.__init__(self, dict) 98 self.request = request 98 99 if processors is None: 99 100 processors = () 100 101 else: -
tests/regressiontests/urlpatterns_reverse/urlconf1.py
1 from django.conf.urls.defaults import * 2 3 import urlconf2 4 5 def empty_view(request): 6 pass 7 8 urlpatterns = patterns('teacher_survey.views', 9 url(r'^test/me/$', empty_view, name='test1'), 10 url(r'^into_urlconf2/', include(urlconf2)) 11 ) 12 -
tests/regressiontests/urlpatterns_reverse/urlconf2.py
1 from django.conf.urls.defaults import * 2 3 def empty_view2(request): 4 pass 5 6 urlpatterns = patterns('teacher_survey.views', 7 url(r'^second_test/$', empty_view2, name='test2'), 8 ) 9 -
tests/regressiontests/urlpatterns_reverse/tests.py
1 1 "Unit tests for reverse URL lookup" 2 2 3 from django.core.urlresolvers import reverse_helper, NoReverseMatch 4 import re,unittest3 import re 4 import unittest 5 5 6 from django.core.urlresolvers import reverse_helper, NoReverseMatch, reverse 7 from django.conf import settings 8 from django.http import HttpRequest 9 from django.template import Template, Context, RequestContext 10 11 import urlconf1 12 import urlconf2 13 6 14 test_data = ( 7 15 ('^places/(\d+)/$', 'places/3/', [3], {}), 8 16 ('^places/(\d+)/$', 'places/3/', ['3'], {}), … … 35 43 else: 36 44 self.assertEquals(got, expected) 37 45 38 if __name__ == "__main__": 39 run_tests(1) 46 class RequestAwareReversing(unittest.TestCase): 47 def setUp(self): 48 self.root_urlconf = settings.ROOT_URLCONF 49 50 def tearDown(self): 51 settings.ROOT_URLCONF = self.root_urlconf 52 53 def test_reverse(self): 54 settings.ROOT_URLCONF = urlconf1 55 # Control 56 self.assertEqual(reverse('test1'), '/test/me/') 57 self.assertEqual(reverse('test2'), '/into_urlconf2/second_test/') 58 # urlconf1 (== control) 59 self.assertEqual(reverse('test1', urlconf=urlconf1), '/test/me/') 60 self.assertEqual(reverse('test2', urlconf=urlconf1), 61 '/into_urlconf2/second_test/') 62 # urlconf2 63 self.assertRaises(NoReverseMatch, 64 lambda: reverse('test1', urlconf=urlconf2)) 65 self.assertEqual(reverse('test2', urlconf=urlconf2), '/second_test/') 66 # urlconf2 via a request object 67 request = HttpRequest() 68 request.urlconf = urlconf2 69 self.assertRaises(NoReverseMatch, 70 lambda: reverse('test1', urlconf=request)) 71 self.assertEqual(reverse('test2', urlconf=request), '/second_test/') 72 73 def test_url_tag(self): 74 settings.ROOT_URLCONF = urlconf1 75 request = HttpRequest() 76 # Rendered with Context rather than RequestContext 77 c = Context() 78 self.assertEqual(Template('{% url test1 %}').render(c), '/test/me/') 79 self.assertEqual(Template('{% url test2 %}').render(c), 80 '/into_urlconf2/second_test/') 81 # Rendered with RequestContext without a request.urlconf 82 c = RequestContext(request) 83 self.assertEqual(Template('{% url test1 %}').render(c), '/test/me/') 84 self.assertEqual(Template('{% url test2 %}').render(c), 85 '/into_urlconf2/second_test/') 86 # Rendered with RequestContext with a request.urlconf 87 request.urlconf = urlconf2 88 c = RequestContext(request) 89 self.assertEqual(Template('{% url test1 %}').render(c), '') 90 self.assertEqual(Template('{% url test2 %}').render(c), 91 '/second_test/') -
docs/url_dispatch.txt
32 32 When a user requests a page from your Django-powered site, this is the 33 33 algorithm the system follows to determine which Python code to execute: 34 34 35 1. Django looks at the ``ROOT_URLCONF`` setting in your `settings file`_. 35 1. Django decides on which URLconf module to use. First, Django looks for a 36 ``urlconf`` attribute on the ``request`` object. 37 Under most situations, this attribute will not be found, in which case 38 Django looks at the ``ROOT_URLCONF`` setting in your `settings file`_. 36 39 This should be a string representing the full Python import path to your 37 40 URLconf. For example: ``"mydjangoapps.urls"``. 38 41 2. Django loads that Python module and looks for the variable … … 596 599 597 600 .. _model API documentation: ../model-api/#the-permalink-decorator 598 601 602 Overriding the URLconf 603 ====================== 604 605 As explained in `how Django processes a request`_, the URLconf module used by 606 Django can be altered via custom middleware by setting ``request.urlconf`` to a 607 string representing the full Python import path to the URLconf. 608 609 If you are using any such middleware, you will need to consider that Django's 610 reverse URL resolution methods need to be made aware of the ``request`` object 611 so they can use the right URLconf: 612 613 * When you use the ``{% url %}`` tag in a template, render it with a 614 ``RequestContext`` so the tag can check the ``request`` object. 615 616 * For ease of use, the ``urlconf`` argument of ``reverse()`` also accepts a 617 ``request`` object. So when you use ``reverse()``, pass ``request`` as 618 the ``urlconf`` argument:: 619 620 reverse('appname.viewname', urlconf=request) 621 622 Using ``reverse()`` without access to ``request`` (such as outside a view) or 623 using the ``permalink`` decorator will mean that the returning URL will only be 624 resolved from the default URLconf as defined in ``settings.ROOT_URLCONF``.