Removed current_app argument to render() and TemplateResponse().

Per deprecation timeline.
This commit is contained in:
Tim Graham 2015-09-03 15:52:04 -04:00
parent 75374d3797
commit 5e450c52aa
15 changed files with 19 additions and 175 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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 <topics-http-reversing-url-namespaces>`
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

View File

@ -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<topics-http-reversing-url-namespaces>`.
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)

View File

@ -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 <topics-http-reversing-url-namespaces>`
for more information.
.. deprecated:: 1.8
The ``current_app`` argument is deprecated. Instead you should set
``request.current_app``.
``using``
The :setting:`NAME <TEMPLATES-NAME>` of a template engine to use for
loading the template.

View File

@ -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
<django.http.HttpRequest.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

View File

@ -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/')

View File

@ -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),
]

View File

@ -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))

View File

@ -1 +0,0 @@
{% load custom %}{% current_app %}

View File

@ -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__"""

View File

@ -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

View File

@ -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))