Loading django/template/context.py +4 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,10 @@ class Context(BaseContext): def current_app(self): return None if self._current_app is _current_app_undefined else self._current_app @property def is_current_app_set(self): return self._current_app is not _current_app_undefined @contextmanager def bind_template(self, template): if self.template is not None: Loading django/template/defaulttags.py +9 −2 Original line number Diff line number Diff line Loading @@ -479,9 +479,16 @@ class URLNode(Node): try: current_app = context.request.current_app except AttributeError: # Change the fallback value to None when the deprecation path for # Leave only the else block when the deprecation path for # Context.current_app completes in Django 1.10. # Can also remove the Context.is_current_app_set property. if context.is_current_app_set: current_app = context.current_app else: try: current_app = context.request.resolver_match.namespace except AttributeError: current_app = None # Try to look up the URL twice: once given the view name, and again # relative to what we guess is the "main" app. If they both fail, Loading docs/releases/1.9.txt +6 −0 Original line number Diff line number Diff line Loading @@ -895,6 +895,12 @@ Miscellaneous whitespace by default. This can be disabled by setting the new :attr:`~django.forms.CharField.strip` argument to ``False``. * If neither :attr:`request.current_app <django.http.HttpRequest.current_app>` nor :class:`Context.current_app <django.template.Context>` are set, the :ttag:`url` template tag will now use the namespace of the current request. Set ``request.current_app`` to ``None`` if you don't want to use a namespace hint. .. _deprecated-features-1.9: Features deprecated in 1.9 Loading docs/topics/http/urls.txt +15 −14 Original line number Diff line number Diff line Loading @@ -669,11 +669,16 @@ the fully qualified name into parts and then tries the following lookup: example, ``'polls'``). This will yield a list of instances of that application. 2. If there is a *current* application defined, Django finds and returns the URL resolver for that instance. The *current* application can be specified as an attribute on the request. Applications that expect to have multiple deployments should set the ``current_app`` attribute on the ``request`` being processed. 2. If there is a current application defined, Django finds and returns the URL resolver for that instance. The current application can be specified with the ``current_app`` argument to the :func:`~django.core.urlresolvers.reverse()` function. The :ttag:`url` template tag uses the namespace of the currently resolved view as the current application in a :class:`~django.template.RequestContext`. You can override this default by setting the current application on the :attr:`request.current_app <django.http.HttpRequest.current_app>` attribute. .. versionchanged:: 1.8 Loading @@ -682,8 +687,11 @@ the fully qualified name into parts and then tries the following lookup: :class:`~django.template.RequestContext` that is used to render a template. The current application can also be specified manually as an argument to the :func:`~django.core.urlresolvers.reverse` function. .. versionchanged:: 1.9 Previously, the :ttag:`url` template tag did not use the namespace of the currently resolved view and you had to set the ``current_app`` attribute on the request. 3. If there is no current application. Django looks for a default application instance. The default application instance is the instance Loading Loading @@ -751,13 +759,6 @@ Using this setup, the following lookups are possible: {% url 'polls:index' %} Note that reversing in the template requires the ``current_app`` be added as an attribute to the ``request`` like this:: def render_to_response(self, context, **response_kwargs): self.request.current_app = self.request.resolver_match.namespace return super(DetailView, self).render_to_response(context, **response_kwargs) * If there is no current instance - say, if we were rendering a page somewhere else on the site - ``'polls:index'`` will resolve to the last registered instance of ``polls``. Since there is no default instance Loading tests/template_tests/syntax_tests/test_url.py +31 −3 Original line number Diff line number Diff line # coding: utf-8 from django.core.urlresolvers import NoReverseMatch from django.template import TemplateSyntaxError from django.test import SimpleTestCase, ignore_warnings, override_settings from django.core.urlresolvers import NoReverseMatch, resolve from django.template import RequestContext, TemplateSyntaxError from django.test import ( RequestFactory, SimpleTestCase, ignore_warnings, override_settings, ) from django.utils.deprecation import RemovedInDjango110Warning from ..utils import setup Loading Loading @@ -252,3 +254,29 @@ class UrlTagTests(SimpleTestCase): def test_url_asvar03(self): output = self.engine.render_to_string('url-asvar03') self.assertEqual(output, '') @setup({'url-namespace01': '{% url "app:named.client" 42 %}'}) def test_url_namespace01(self): request = RequestFactory().get('/') request.resolver_match = resolve('/ns1/') template = self.engine.get_template('url-namespace01') context = RequestContext(request) output = template.render(context) self.assertEqual(output, '/ns1/named-client/42/') @setup({'url-namespace02': '{% url "app:named.client" 42 %}'}) def test_url_namespace02(self): request = RequestFactory().get('/') request.resolver_match = resolve('/ns2/') template = self.engine.get_template('url-namespace02') context = RequestContext(request) output = template.render(context) self.assertEqual(output, '/ns2/named-client/42/') @setup({'url-namespace03': '{% url "app:named.client" 42 %}'}) def test_url_namespace03(self): request = RequestFactory().get('/') template = self.engine.get_template('url-namespace03') context = RequestContext(request) output = template.render(context) self.assertEqual(output, '/ns2/named-client/42/') Loading
django/template/context.py +4 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,10 @@ class Context(BaseContext): def current_app(self): return None if self._current_app is _current_app_undefined else self._current_app @property def is_current_app_set(self): return self._current_app is not _current_app_undefined @contextmanager def bind_template(self, template): if self.template is not None: Loading
django/template/defaulttags.py +9 −2 Original line number Diff line number Diff line Loading @@ -479,9 +479,16 @@ class URLNode(Node): try: current_app = context.request.current_app except AttributeError: # Change the fallback value to None when the deprecation path for # Leave only the else block when the deprecation path for # Context.current_app completes in Django 1.10. # Can also remove the Context.is_current_app_set property. if context.is_current_app_set: current_app = context.current_app else: try: current_app = context.request.resolver_match.namespace except AttributeError: current_app = None # Try to look up the URL twice: once given the view name, and again # relative to what we guess is the "main" app. If they both fail, Loading
docs/releases/1.9.txt +6 −0 Original line number Diff line number Diff line Loading @@ -895,6 +895,12 @@ Miscellaneous whitespace by default. This can be disabled by setting the new :attr:`~django.forms.CharField.strip` argument to ``False``. * If neither :attr:`request.current_app <django.http.HttpRequest.current_app>` nor :class:`Context.current_app <django.template.Context>` are set, the :ttag:`url` template tag will now use the namespace of the current request. Set ``request.current_app`` to ``None`` if you don't want to use a namespace hint. .. _deprecated-features-1.9: Features deprecated in 1.9 Loading
docs/topics/http/urls.txt +15 −14 Original line number Diff line number Diff line Loading @@ -669,11 +669,16 @@ the fully qualified name into parts and then tries the following lookup: example, ``'polls'``). This will yield a list of instances of that application. 2. If there is a *current* application defined, Django finds and returns the URL resolver for that instance. The *current* application can be specified as an attribute on the request. Applications that expect to have multiple deployments should set the ``current_app`` attribute on the ``request`` being processed. 2. If there is a current application defined, Django finds and returns the URL resolver for that instance. The current application can be specified with the ``current_app`` argument to the :func:`~django.core.urlresolvers.reverse()` function. The :ttag:`url` template tag uses the namespace of the currently resolved view as the current application in a :class:`~django.template.RequestContext`. You can override this default by setting the current application on the :attr:`request.current_app <django.http.HttpRequest.current_app>` attribute. .. versionchanged:: 1.8 Loading @@ -682,8 +687,11 @@ the fully qualified name into parts and then tries the following lookup: :class:`~django.template.RequestContext` that is used to render a template. The current application can also be specified manually as an argument to the :func:`~django.core.urlresolvers.reverse` function. .. versionchanged:: 1.9 Previously, the :ttag:`url` template tag did not use the namespace of the currently resolved view and you had to set the ``current_app`` attribute on the request. 3. If there is no current application. Django looks for a default application instance. The default application instance is the instance Loading Loading @@ -751,13 +759,6 @@ Using this setup, the following lookups are possible: {% url 'polls:index' %} Note that reversing in the template requires the ``current_app`` be added as an attribute to the ``request`` like this:: def render_to_response(self, context, **response_kwargs): self.request.current_app = self.request.resolver_match.namespace return super(DetailView, self).render_to_response(context, **response_kwargs) * If there is no current instance - say, if we were rendering a page somewhere else on the site - ``'polls:index'`` will resolve to the last registered instance of ``polls``. Since there is no default instance Loading
tests/template_tests/syntax_tests/test_url.py +31 −3 Original line number Diff line number Diff line # coding: utf-8 from django.core.urlresolvers import NoReverseMatch from django.template import TemplateSyntaxError from django.test import SimpleTestCase, ignore_warnings, override_settings from django.core.urlresolvers import NoReverseMatch, resolve from django.template import RequestContext, TemplateSyntaxError from django.test import ( RequestFactory, SimpleTestCase, ignore_warnings, override_settings, ) from django.utils.deprecation import RemovedInDjango110Warning from ..utils import setup Loading Loading @@ -252,3 +254,29 @@ class UrlTagTests(SimpleTestCase): def test_url_asvar03(self): output = self.engine.render_to_string('url-asvar03') self.assertEqual(output, '') @setup({'url-namespace01': '{% url "app:named.client" 42 %}'}) def test_url_namespace01(self): request = RequestFactory().get('/') request.resolver_match = resolve('/ns1/') template = self.engine.get_template('url-namespace01') context = RequestContext(request) output = template.render(context) self.assertEqual(output, '/ns1/named-client/42/') @setup({'url-namespace02': '{% url "app:named.client" 42 %}'}) def test_url_namespace02(self): request = RequestFactory().get('/') request.resolver_match = resolve('/ns2/') template = self.engine.get_template('url-namespace02') context = RequestContext(request) output = template.render(context) self.assertEqual(output, '/ns2/named-client/42/') @setup({'url-namespace03': '{% url "app:named.client" 42 %}'}) def test_url_namespace03(self): request = RequestFactory().get('/') template = self.engine.get_template('url-namespace03') context = RequestContext(request) output = template.render(context) self.assertEqual(output, '/ns2/named-client/42/')