From 5e450c52aafb62b9d83c8ac08892e0b92cbec4aa Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Thu, 3 Sep 2015 15:52:04 -0400 Subject: [PATCH] Removed current_app argument to render() and TemplateResponse(). Per deprecation timeline. --- django/shortcuts.py | 23 ++---------- django/template/context.py | 35 ++----------------- django/template/defaulttags.py | 16 ++------- django/template/response.py | 15 ++------ docs/ref/template-response.txt | 12 +------ docs/ref/templates/api.txt | 7 +--- docs/topics/http/shortcuts.txt | 12 +------ docs/topics/http/urls.txt | 7 ---- tests/shortcuts/tests.py | 10 ------ tests/shortcuts/urls.py | 2 -- tests/shortcuts/views.py | 16 --------- .../templates/test_incl_tag_current_app.html | 1 - .../template_tests/templatetags/inclusion.py | 7 ---- tests/template_tests/test_custom.py | 18 +--------- tests/template_tests/test_response.py | 13 ++++--- 15 files changed, 19 insertions(+), 175 deletions(-) delete mode 100644 tests/template_tests/templates/test_incl_tag_current_app.html diff --git a/django/shortcuts.py b/django/shortcuts.py index 7c7e61fb5c..4bfc2dcfb2 100644 --- a/django/shortcuts.py +++ b/django/shortcuts.py @@ -3,9 +3,6 @@ This module collects helper functions and classes that "span" multiple levels of MVC. In other words, these functions/classes introduce controlled coupling for convenience's sake. """ - -import warnings - from django.core import urlresolvers from django.db.models.base import ModelBase from django.db.models.manager import Manager @@ -14,12 +11,10 @@ from django.http import ( Http404, HttpResponse, HttpResponsePermanentRedirect, HttpResponseRedirect, ) from django.template import RequestContext, loader -from django.template.context import _current_app_undefined from django.template.engine import ( _context_instance_undefined, _dictionary_undefined, _dirs_undefined, ) from django.utils import six -from django.utils.deprecation import RemovedInDjango110Warning from django.utils.encoding import force_text from django.utils.functional import Promise @@ -49,7 +44,7 @@ def render_to_response(template_name, context=None, def render(request, template_name, context=None, context_instance=_context_instance_undefined, - content_type=None, status=None, current_app=_current_app_undefined, + content_type=None, status=None, dirs=_dirs_undefined, dictionary=_dictionary_undefined, using=None): """ @@ -58,32 +53,18 @@ def render(request, template_name, context=None, Uses a RequestContext by default. """ if (context_instance is _context_instance_undefined - and current_app is _current_app_undefined and dirs is _dirs_undefined and dictionary is _dictionary_undefined): # No deprecated arguments were passed - use the new code path # In Django 1.10, request should become a positional argument. content = loader.render_to_string( template_name, context, request=request, using=using) - else: # Some deprecated arguments were passed - use the legacy code path if context_instance is not _context_instance_undefined: - if current_app is not _current_app_undefined: - raise ValueError('If you provide a context_instance you must ' - 'set its current_app before calling render()') + pass else: context_instance = RequestContext(request) - if current_app is not _current_app_undefined: - warnings.warn( - "The current_app argument of render is deprecated. " - "Set the current_app attribute of request instead.", - RemovedInDjango110Warning, stacklevel=2) - request.current_app = current_app - # Directly set the private attribute to avoid triggering the - # warning in RequestContext.__init__. - context_instance._current_app = current_app - content = loader.render_to_string( template_name, context, context_instance, dirs, dictionary, using=using) diff --git a/django/template/context.py b/django/template/context.py index b563e526f2..2643e927f4 100644 --- a/django/template/context.py +++ b/django/template/context.py @@ -1,14 +1,9 @@ -import warnings from contextlib import contextmanager from copy import copy -from django.utils.deprecation import RemovedInDjango110Warning - # Hard-coded processor for easier use of CSRF protection. _builtin_context_processors = ('django.template.context_processors.csrf',) -_current_app_undefined = object() - class ContextPopException(Exception): "pop() has been called more times than push()" @@ -135,16 +130,8 @@ class BaseContext(object): class Context(BaseContext): "A stack container for variable context" - def __init__(self, dict_=None, autoescape=True, - current_app=_current_app_undefined, - use_l10n=None, use_tz=None): - if current_app is not _current_app_undefined: - warnings.warn( - "The current_app argument of Context is deprecated. Use " - "RequestContext and set the current_app attribute of its " - "request instead.", RemovedInDjango110Warning, stacklevel=2) + def __init__(self, dict_=None, autoescape=True, use_l10n=None, use_tz=None): self.autoescape = autoescape - self._current_app = current_app self.use_l10n = use_l10n self.use_tz = use_tz self.template_name = "unknown" @@ -154,14 +141,6 @@ class Context(BaseContext): self.template = None super(Context, self).__init__(dict_) - @property - 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: @@ -222,19 +201,9 @@ class RequestContext(Context): Additional processors can be specified as a list of callables using the "processors" keyword argument. """ - def __init__(self, request, dict_=None, processors=None, - current_app=_current_app_undefined, - use_l10n=None, use_tz=None): - # current_app isn't passed here to avoid triggering the deprecation - # warning in Context.__init__. + def __init__(self, request, dict_=None, processors=None, use_l10n=None, use_tz=None): super(RequestContext, self).__init__( dict_, use_l10n=use_l10n, use_tz=use_tz) - if current_app is not _current_app_undefined: - warnings.warn( - "The current_app argument of RequestContext is deprecated. " - "Set the current_app attribute of its request instead.", - RemovedInDjango110Warning, stacklevel=2) - self._current_app = current_app self.request = request self._processors = () if processors is None else tuple(processors) self._processors_index = len(self.dicts) diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py index 9f0389c0e4..481df8c14e 100644 --- a/django/template/defaulttags.py +++ b/django/template/defaulttags.py @@ -432,23 +432,11 @@ class URLNode(Node): smart_text(k, 'ascii'): v.resolve(context) for k, v in self.kwargs.items() } - view_name = self.view_name.resolve(context) - try: - current_app = context.request.current_app + current_app = context.request.resolver_match.namespace except AttributeError: - # 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 - + 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, # re-raise the NoReverseMatch unless we're using the diff --git a/django/template/response.py b/django/template/response.py index 17b6066a81..fb2e5cd9f9 100644 --- a/django/template/response.py +++ b/django/template/response.py @@ -6,7 +6,7 @@ from django.utils.deprecation import RemovedInDjango110Warning from .backends.django import Template as BackendTemplate from .base import Template -from .context import Context, RequestContext, _current_app_undefined +from .context import Context, RequestContext from .loader import get_template, select_template @@ -190,19 +190,10 @@ class SimpleTemplateResponse(HttpResponse): class TemplateResponse(SimpleTemplateResponse): - rendering_attrs = SimpleTemplateResponse.rendering_attrs + ['_request', '_current_app'] + rendering_attrs = SimpleTemplateResponse.rendering_attrs + ['_request'] def __init__(self, request, template, context=None, content_type=None, - status=None, current_app=_current_app_undefined, charset=None, - using=None): - # As a convenience we'll allow callers to provide current_app without - # having to avoid needing to create the RequestContext directly - if current_app is not _current_app_undefined: - warnings.warn( - "The current_app argument of TemplateResponse is deprecated. " - "Set the current_app attribute of its request instead.", - RemovedInDjango110Warning, stacklevel=2) - request.current_app = current_app + status=None, charset=None, using=None): super(TemplateResponse, self).__init__( template, context, content_type, status, charset, using) self._request = request diff --git a/docs/ref/template-response.txt b/docs/ref/template-response.txt index ecf984cdf3..8fbc7b1c99 100644 --- a/docs/ref/template-response.txt +++ b/docs/ref/template-response.txt @@ -189,7 +189,7 @@ TemplateResponse objects Methods ------- -.. method:: TemplateResponse.__init__(request, template, context=None, content_type=None, status=None, current_app=None, charset=None, using=None) +.. method:: TemplateResponse.__init__(request, template, context=None, content_type=None, status=None, charset=None, using=None) Instantiates a :class:`~django.template.response.TemplateResponse` object with the given request, template, context, content type, HTTP status, and @@ -224,16 +224,6 @@ Methods ``status`` The HTTP status code for the response. - ``current_app`` - A hint indicating which application contains the current view. See the - :ref:`namespaced URL resolution strategy ` - for more information. - - .. deprecated:: 1.8 - - The ``current_app`` argument is deprecated. Instead you should set - ``request.current_app``. - ``charset`` The charset in which the response will be encoded. If not given it will be extracted from ``content_type``, and if that is unsuccessful, the diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt index 5f6e12934c..ba649aa60f 100644 --- a/docs/ref/templates/api.txt +++ b/docs/ref/templates/api.txt @@ -194,7 +194,7 @@ Once you have a compiled :class:`Template` object, you can render a context with it. You can reuse the same template to render it several times with different contexts. -.. class:: Context(dict_=None, current_app=_current_app_undefined) +.. class:: Context(dict_=None) This class lives at ``django.template.Context``. The constructor takes two optional arguments: @@ -205,11 +205,6 @@ different contexts. to help :ref:`resolve namespaced URLs`. If you're not using namespaced URLs, you can ignore this argument. - .. deprecated:: 1.8 - - The ``current_app`` argument is deprecated. If you need it, you must - now use a :class:`RequestContext` instead of a :class:`Context`. - For details, see :ref:`playing-with-context` below. .. method:: Template.render(context) diff --git a/docs/topics/http/shortcuts.txt b/docs/topics/http/shortcuts.txt index ab8c237ee9..43b5ef5868 100644 --- a/docs/topics/http/shortcuts.txt +++ b/docs/topics/http/shortcuts.txt @@ -15,7 +15,7 @@ introduce controlled coupling for convenience's sake. ``render`` ========== -.. function:: render(request, template_name, context=None, context_instance=_context_instance_undefined, content_type=None, status=None, current_app=_current_app_undefined, dirs=_dirs_undefined, using=None) +.. function:: render(request, template_name, context=None, context_instance=_context_instance_undefined, content_type=None, status=None, dirs=_dirs_undefined, using=None) Combines a given template with a given context dictionary and returns an :class:`~django.http.HttpResponse` object with that rendered text. @@ -67,16 +67,6 @@ Optional arguments ``status`` The status code for the response. Defaults to ``200``. -``current_app`` - A hint indicating which application contains the current view. See the - :ref:`namespaced URL resolution strategy ` - for more information. - - .. deprecated:: 1.8 - - The ``current_app`` argument is deprecated. Instead you should set - ``request.current_app``. - ``using`` The :setting:`NAME ` of a template engine to use for loading the template. diff --git a/docs/topics/http/urls.txt b/docs/topics/http/urls.txt index e48ac9d7ee..7bd8fc21a3 100644 --- a/docs/topics/http/urls.txt +++ b/docs/topics/http/urls.txt @@ -680,13 +680,6 @@ the fully qualified name into parts and then tries the following lookup: setting the current application on the :attr:`request.current_app ` attribute. - .. versionchanged:: 1.8 - - In previous versions of Django, you had to set the ``current_app`` - attribute on any :class:`~django.template.Context` or - :class:`~django.template.RequestContext` that is used to render a - template. - .. versionchanged:: 1.9 Previously, the :ttag:`url` template tag did not use the namespace of the diff --git a/tests/shortcuts/tests.py b/tests/shortcuts/tests.py index ef7a0edc7a..5c44ab20f5 100644 --- a/tests/shortcuts/tests.py +++ b/tests/shortcuts/tests.py @@ -102,19 +102,9 @@ class ShortcutTests(SimpleTestCase): response = self.client.get('/render/using/?using=jinja2') self.assertEqual(response.content, b'Jinja2\n') - @ignore_warnings(category=RemovedInDjango110Warning) - def test_render_with_current_app(self): - response = self.client.get('/render/current_app/') - self.assertEqual(response.context.request.current_app, "foobar_app") - @ignore_warnings(category=RemovedInDjango110Warning) def test_render_with_dirs(self): response = self.client.get('/render/dirs/') self.assertEqual(response.status_code, 200) self.assertEqual(response.content, b'spam eggs\n') self.assertEqual(response['Content-Type'], 'text/html; charset=utf-8') - - @ignore_warnings(category=RemovedInDjango110Warning) - def test_render_with_current_app_conflict(self): - with self.assertRaises(ValueError): - self.client.get('/render/current_app_conflict/') diff --git a/tests/shortcuts/urls.py b/tests/shortcuts/urls.py index 449a840f73..e125709296 100644 --- a/tests/shortcuts/urls.py +++ b/tests/shortcuts/urls.py @@ -18,6 +18,4 @@ urlpatterns = [ url(r'^render/dirs/$', views.render_with_dirs), url(r'^render/status/$', views.render_view_with_status), url(r'^render/using/$', views.render_view_with_using), - url(r'^render/current_app/$', views.render_view_with_current_app), - url(r'^render/current_app_conflict/$', views.render_view_with_current_app_conflict), ] diff --git a/tests/shortcuts/views.py b/tests/shortcuts/views.py index f988edf8d9..e4638106ac 100644 --- a/tests/shortcuts/views.py +++ b/tests/shortcuts/views.py @@ -109,19 +109,3 @@ def render_view_with_status(request): def render_view_with_using(request): using = request.GET.get('using') return render(request, 'shortcuts/using.html', using=using) - - -def render_view_with_current_app(request): - return render(request, 'shortcuts/render_test.html', { - 'foo': 'FOO', - 'bar': 'BAR', - }, current_app="foobar_app") - - -def render_view_with_current_app_conflict(request): - # This should fail because we don't passing both a current_app and - # context_instance: - return render(request, 'shortcuts/render_test.html', { - 'foo': 'FOO', - 'bar': 'BAR', - }, current_app="foobar_app", context_instance=RequestContext(request)) diff --git a/tests/template_tests/templates/test_incl_tag_current_app.html b/tests/template_tests/templates/test_incl_tag_current_app.html deleted file mode 100644 index ab2fe63b6f..0000000000 --- a/tests/template_tests/templates/test_incl_tag_current_app.html +++ /dev/null @@ -1 +0,0 @@ -{% load custom %}{% current_app %} diff --git a/tests/template_tests/templatetags/inclusion.py b/tests/template_tests/templatetags/inclusion.py index 185cdb1917..57fad868e7 100644 --- a/tests/template_tests/templatetags/inclusion.py +++ b/tests/template_tests/templatetags/inclusion.py @@ -166,13 +166,6 @@ def inclusion_only_unlimited_args_from_template(*args): inclusion_only_unlimited_args_from_template.anything = "Expected inclusion_only_unlimited_args_from_template __dict__" -@register.inclusion_tag('test_incl_tag_current_app.html', takes_context=True) -def inclusion_tag_current_app(context): - """Expected inclusion_tag_current_app __doc__""" - return {} -inclusion_tag_current_app.anything = "Expected inclusion_tag_current_app __dict__" - - @register.inclusion_tag('test_incl_tag_use_l10n.html', takes_context=True) def inclusion_tag_use_l10n(context): """Expected inclusion_tag_use_l10n __doc__""" diff --git a/tests/template_tests/test_custom.py b/tests/template_tests/test_custom.py index 48252e1788..12331afce8 100644 --- a/tests/template_tests/test_custom.py +++ b/tests/template_tests/test_custom.py @@ -6,10 +6,9 @@ from unittest import skipUnless from django.template import Context, Engine, TemplateSyntaxError from django.template.base import Node from django.template.library import InvalidTemplateLibrary -from django.test import SimpleTestCase, ignore_warnings +from django.test import SimpleTestCase from django.test.utils import extend_sys_path from django.utils import six -from django.utils.deprecation import RemovedInDjango110Warning from .templatetags import custom, inclusion from .utils import ROOT @@ -270,23 +269,8 @@ class InclusionTagTests(TagTestCase): self.verify_tag(inclusion.inclusion_only_unlimited_args, 'inclusion_only_unlimited_args') self.verify_tag(inclusion.inclusion_tag_without_context_parameter, 'inclusion_tag_without_context_parameter') self.verify_tag(inclusion.inclusion_tag_use_l10n, 'inclusion_tag_use_l10n') - self.verify_tag(inclusion.inclusion_tag_current_app, 'inclusion_tag_current_app') self.verify_tag(inclusion.inclusion_unlimited_args_kwargs, 'inclusion_unlimited_args_kwargs') - @ignore_warnings(category=RemovedInDjango110Warning) - def test_15070_current_app(self): - """ - Test that inclusion tag passes down `current_app` of context to the - Context of the included/rendered template as well. - """ - c = Context({}) - t = self.engine.from_string('{% load inclusion %}{% inclusion_tag_current_app %}') - self.assertEqual(t.render(c).strip(), 'None') - - # That part produces the deprecation warning - c = Context({}, current_app='advanced') - self.assertEqual(t.render(c).strip(), 'advanced') - def test_15070_use_l10n(self): """ Test that inclusion tag passes down `use_l10n` of context to the diff --git a/tests/template_tests/test_response.py b/tests/template_tests/test_response.py index 36a0ba704d..8fea389f53 100644 --- a/tests/template_tests/test_response.py +++ b/tests/template_tests/test_response.py @@ -282,11 +282,6 @@ class TemplateResponseTest(SimpleTestCase): response = TemplateResponse(request, 'template_tests/using.html', using='jinja2').render() self.assertEqual(response.content, b'Jinja2\n') - @ignore_warnings(category=RemovedInDjango110Warning) - def test_custom_app(self): - self._response('{{ foo }}', current_app="foobar") - self.assertEqual(self._request.current_app, 'foobar') - def test_pickling(self): # Create a template response. The context is # known to be unpickleable (e.g., a function). @@ -310,8 +305,12 @@ class TemplateResponseTest(SimpleTestCase): # ...and the unpickled response doesn't have the # template-related attributes, so it can't be re-rendered - template_attrs = ('template_name', 'context_data', - '_post_render_callbacks', '_request', '_current_app') + template_attrs = ( + 'template_name', + 'context_data', + '_post_render_callbacks', + '_request', + ) for attr in template_attrs: self.assertFalse(hasattr(unpickled_response, attr))