Skip to content

Commit fdbfc98

Browse files
committed
Deprecated some arguments of django.shortcuts.render(_to_response).
dictionary and context_instance and superseded by context. Refactored tests that relied context_instance with more modern idioms.
1 parent a0141f9 commit fdbfc98

File tree

12 files changed

+136
-91
lines changed

12 files changed

+136
-91
lines changed

django/contrib/auth/tests/test_context_processors.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ def test_permlookupdict_in(self):
6565
TEMPLATE_DIRS=(
6666
os.path.join(os.path.dirname(upath(__file__)), 'templates'),
6767
),
68+
TEMPLATE_CONTEXT_PROCESSORS=(
69+
'django.contrib.auth.context_processors.auth',
70+
'django.contrib.messages.context_processors.messages'
71+
),
6872
ROOT_URLCONF='django.contrib.auth.tests.urls',
6973
USE_TZ=False, # required for loading the fixture
7074
PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',),
@@ -80,9 +84,6 @@ class AuthContextProcessorTests(TestCase):
8084
'django.contrib.sessions.middleware.SessionMiddleware',
8185
'django.contrib.auth.middleware.AuthenticationMiddleware',
8286
),
83-
TEMPLATE_CONTEXT_PROCESSORS=(
84-
'django.contrib.auth.context_processors.auth',
85-
),
8687
)
8788
def test_session_not_accessed(self):
8889
"""
@@ -97,9 +98,6 @@ def test_session_not_accessed(self):
9798
'django.contrib.sessions.middleware.SessionMiddleware',
9899
'django.contrib.auth.middleware.AuthenticationMiddleware',
99100
),
100-
TEMPLATE_CONTEXT_PROCESSORS=(
101-
'django.contrib.auth.context_processors.auth',
102-
),
103101
)
104102
def test_session_is_accessed(self):
105103
"""

django/contrib/auth/tests/urls.py

+13-18
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
from django.conf.urls import url, include
22
from django.contrib import admin
3-
from django.contrib.auth import context_processors
43
from django.contrib.auth.forms import AuthenticationForm
54
from django.contrib.auth.urls import urlpatterns
65
from django.contrib.auth import views
76
from django.contrib.auth.decorators import login_required
87
from django.contrib.messages.api import info
98
from django.http import HttpResponse, HttpRequest
10-
from django.shortcuts import render_to_response
9+
from django.shortcuts import render
1110
from django.template import Template, RequestContext
1211
from django.views.decorators.cache import never_cache
1312

@@ -27,39 +26,35 @@ def remote_user_auth_view(request):
2726

2827

2928
def auth_processor_no_attr_access(request):
30-
render_to_response('context_processors/auth_attrs_no_access.html',
31-
context_instance=RequestContext(request, {}, processors=[context_processors.auth]))
29+
render(request, 'context_processors/auth_attrs_no_access.html')
3230
# *After* rendering, we check whether the session was accessed
33-
return render_to_response('context_processors/auth_attrs_test_access.html',
34-
{'session_accessed': request.session.accessed})
31+
return render(request,
32+
'context_processors/auth_attrs_test_access.html',
33+
{'session_accessed': request.session.accessed})
3534

3635

3736
def auth_processor_attr_access(request):
38-
render_to_response('context_processors/auth_attrs_access.html',
39-
context_instance=RequestContext(request, {}, processors=[context_processors.auth]))
40-
return render_to_response('context_processors/auth_attrs_test_access.html',
41-
{'session_accessed': request.session.accessed})
37+
render(request, 'context_processors/auth_attrs_access.html')
38+
return render(request,
39+
'context_processors/auth_attrs_test_access.html',
40+
{'session_accessed': request.session.accessed})
4241

4342

4443
def auth_processor_user(request):
45-
return render_to_response('context_processors/auth_attrs_user.html',
46-
context_instance=RequestContext(request, {}, processors=[context_processors.auth]))
44+
return render(request, 'context_processors/auth_attrs_user.html')
4745

4846

4947
def auth_processor_perms(request):
50-
return render_to_response('context_processors/auth_attrs_perms.html',
51-
context_instance=RequestContext(request, {}, processors=[context_processors.auth]))
48+
return render(request, 'context_processors/auth_attrs_perms.html')
5249

5350

5451
def auth_processor_perm_in_perms(request):
55-
return render_to_response('context_processors/auth_attrs_perm_in_perms.html',
56-
context_instance=RequestContext(request, {}, processors=[context_processors.auth]))
52+
return render(request, 'context_processors/auth_attrs_perm_in_perms.html')
5753

5854

5955
def auth_processor_messages(request):
6056
info(request, "Message 1")
61-
return render_to_response('context_processors/auth_attrs_messages.html',
62-
context_instance=RequestContext(request, {}, processors=[context_processors.auth]))
57+
return render(request, 'context_processors/auth_attrs_messages.html')
6358

6459

6560
def userpage(request):

django/contrib/gis/admin/widgets.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import logging
22

33
from django.forms.widgets import Textarea
4-
from django.template import loader, Context
4+
from django.template import loader
55
from django.utils import six
66
from django.utils import translation
77

@@ -10,7 +10,7 @@
1010

1111
# Creating a template context that contains Django settings
1212
# values needed by admin map templates.
13-
geo_context = Context({'LANGUAGE_BIDI': translation.get_language_bidi()})
13+
geo_context = {'LANGUAGE_BIDI': translation.get_language_bidi()}
1414
logger = logging.getLogger('django.contrib.gis')
1515

1616

@@ -81,8 +81,8 @@ def render(self, name, value, attrs=None):
8181
# geometry.
8282
self.params['wkt'] = wkt
8383

84-
return loader.render_to_string(self.template, self.params,
85-
context_instance=geo_context)
84+
self.params.update(geo_context)
85+
return loader.render_to_string(self.template, self.params)
8686

8787
def map_options(self):
8888
"Builds the map options hash for the OpenLayers template."

django/shortcuts.py

+32-21
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
of MVC. In other words, these functions/classes introduce controlled coupling
44
for convenience's sake.
55
"""
6-
import warnings
7-
86
from django.template import loader, RequestContext
97
from django.template.context import _current_app_undefined
108
from django.template.engine import (
@@ -16,44 +14,57 @@
1614
from django.db.models.query import QuerySet
1715
from django.core import urlresolvers
1816
from django.utils import six
19-
from django.utils.deprecation import RemovedInDjango20Warning
2017

2118

22-
def render_to_response(template_name, dictionary=_dictionary_undefined,
19+
def render_to_response(template_name, context=None,
2320
context_instance=_context_instance_undefined,
24-
content_type=None, dirs=_dirs_undefined):
21+
content_type=None, status=None, dirs=_dirs_undefined,
22+
dictionary=_dictionary_undefined):
2523
"""
2624
Returns a HttpResponse whose content is filled with the result of calling
2725
django.template.loader.render_to_string() with the passed arguments.
2826
"""
29-
# TODO: refactor to avoid the deprecated code path.
30-
with warnings.catch_warnings():
31-
warnings.filterwarnings("ignore", category=RemovedInDjango20Warning)
32-
content = loader.render_to_string(template_name, dictionary, context_instance, dirs)
27+
if (context_instance is _context_instance_undefined
28+
and dirs is _dirs_undefined
29+
and dictionary is _dictionary_undefined):
30+
# No deprecated arguments were passed - use the new code path
31+
content = loader.get_template(template_name).render(context)
32+
33+
else:
34+
# Some deprecated arguments were passed - use the legacy code path
35+
content = loader.render_to_string(
36+
template_name, context, context_instance, dirs, dictionary)
3337

34-
return HttpResponse(content, content_type)
38+
return HttpResponse(content, content_type, status)
3539

3640

37-
def render(request, template_name, dictionary=_dictionary_undefined,
41+
def render(request, template_name, context=None,
3842
context_instance=_context_instance_undefined,
3943
content_type=None, status=None, current_app=_current_app_undefined,
40-
dirs=_dirs_undefined):
44+
dirs=_dirs_undefined, dictionary=_dictionary_undefined):
4145
"""
4246
Returns a HttpResponse whose content is filled with the result of calling
4347
django.template.loader.render_to_string() with the passed arguments.
4448
Uses a RequestContext by default.
4549
"""
46-
if context_instance is not _context_instance_undefined:
47-
if current_app is not _current_app_undefined:
48-
raise ValueError('If you provide a context_instance you must '
49-
'set its current_app before calling render()')
50+
if (context_instance is _context_instance_undefined
51+
and current_app is _current_app_undefined
52+
and dirs is _dirs_undefined
53+
and dictionary is _dictionary_undefined):
54+
# No deprecated arguments were passed - use the new code path
55+
content = loader.get_template(template_name).render(context, request)
56+
5057
else:
51-
context_instance = RequestContext(request, current_app=current_app)
58+
# Some deprecated arguments were passed - use the legacy code path
59+
if context_instance is not _context_instance_undefined:
60+
if current_app is not _current_app_undefined:
61+
raise ValueError('If you provide a context_instance you must '
62+
'set its current_app before calling render()')
63+
else:
64+
context_instance = RequestContext(request, current_app=current_app)
5265

53-
# TODO: refactor to avoid the deprecated code path.
54-
with warnings.catch_warnings():
55-
warnings.filterwarnings("ignore", category=RemovedInDjango20Warning)
56-
content = loader.render_to_string(template_name, dictionary, context_instance, dirs)
66+
content = loader.render_to_string(
67+
template_name, context, context_instance, dirs, dictionary)
5768

5869
return HttpResponse(content, content_type, status)
5970

docs/internals/deprecation.txt

+2
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ details on these changes.
9393
* The ``dictionary`` and ``context_instance`` parameters for the following
9494
functions will be removed:
9595

96+
* ``django.shortcuts.render()``
97+
* ``django.shortcuts.render_to_response()``
9698
* ``django.template.loader.render_to_string()``
9799

98100
* The ``dirs`` parameter for the following functions will be removed:

docs/ref/contrib/admin/admindocs.txt

+4-6
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ you can document in your view function docstrings include:
9595

9696
For example::
9797

98+
from django.shortcuts import render
99+
98100
from myapp.models import MyModel
99101

100102
def my_view(request, slug):
@@ -103,8 +105,6 @@ For example::
103105

104106
**Context**
105107

106-
``RequestContext``
107-
108108
``mymodel``
109109
An instance of :model:`myapp.MyModel`.
110110

@@ -113,10 +113,8 @@ For example::
113113
:template:`myapp/my_template.html`
114114

115115
"""
116-
return render_to_response('myapp/my_template.html', {
117-
'mymodel': MyModel.objects.get(slug=slug)
118-
}, context_instance=RequestContext(request))
119-
116+
context = {'mymodel': MyModel.objects.get(slug=slug)}
117+
return render(request, 'myapp/my_template.html', context)
120118

121119
Template tags and filters reference
122120
===================================

docs/releases/1.8.txt

+2
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,8 @@ now optional.
12101210
The following functions will no longer accept the ``dictionary`` and
12111211
``context_instance`` parameters in Django 2.0:
12121212

1213+
* ``django.shortcuts.render()``
1214+
* ``django.shortcuts.render_to_response()``
12131215
* ``django.template.loader.render_to_string()``
12141216

12151217
Use the ``context`` parameter instead. When ``dictionary`` is passed as a

docs/topics/http/shortcuts.txt

+34-9
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ introduce controlled coupling for convenience's sake.
1515
``render``
1616
==========
1717

18-
.. function:: render(request, template_name[, dictionary][, context_instance][, content_type][, status][, current_app][, dirs])
18+
.. function:: render(request, template_name[, context][, context_instance][, content_type][, status][, current_app][, dirs])
1919

2020
Combines a given template with a given context dictionary and returns an
2121
:class:`~django.http.HttpResponse` object with that rendered text.
@@ -41,15 +41,24 @@ Required arguments
4141
Optional arguments
4242
------------------
4343

44-
``dictionary``
44+
``context``
4545
A dictionary of values to add to the template context. By default, this
4646
is an empty dictionary. If a value in the dictionary is callable, the
4747
view will call it just before rendering the template.
4848

49+
.. versionchanged:: 1.8
50+
51+
The ``context`` argument used to be called ``dictionary``. That name
52+
is deprecated in Django 1.8 and will be removed in Django 2.0.
53+
4954
``context_instance``
5055
The context instance to render the template with. By default, the template
5156
will be rendered with a ``RequestContext`` instance (filled with values from
52-
``request`` and ``dictionary``).
57+
``request`` and ``context``).
58+
59+
.. deprecated:: 1.8
60+
61+
The ``context_instance`` argument is deprecated. Simply use ``context``.
5362

5463
``content_type``
5564
The MIME type to use for the resulting document. Defaults to the value of
@@ -67,7 +76,7 @@ Optional arguments
6776

6877
The ``dirs`` parameter was added.
6978

70-
.. versionchanged:: 1.8
79+
.. deprecated:: 1.8
7180

7281
The ``dirs`` parameter was deprecated.
7382

@@ -99,7 +108,7 @@ This example is equivalent to::
99108
``render_to_response``
100109
======================
101110

102-
.. function:: render_to_response(template_name[, dictionary][, context_instance][, content_type][, dirs])
111+
.. function:: render_to_response(template_name[, context][, context_instance][, content_type][, status][, dirs])
103112

104113
Renders a given template with a given context dictionary and returns an
105114
:class:`~django.http.HttpResponse` object with that rendered text.
@@ -116,32 +125,48 @@ Required arguments
116125
Optional arguments
117126
------------------
118127

119-
``dictionary``
128+
``context``
120129
A dictionary of values to add to the template context. By default, this
121130
is an empty dictionary. If a value in the dictionary is callable, the
122131
view will call it just before rendering the template.
123132

133+
.. versionchanged:: 1.8
134+
135+
The ``context`` argument used to be called ``dictionary``. That name
136+
is deprecated in Django 1.8 and will be removed in Django 2.0.
137+
124138
``context_instance``
125139
The context instance to render the template with. By default, the template
126140
will be rendered with a :class:`~django.template.Context` instance (filled
127-
with values from ``dictionary``). If you need to use :ref:`context
141+
with values from ``context``). If you need to use :ref:`context
128142
processors <subclassing-context-requestcontext>`, render the template with
129143
a :class:`~django.template.RequestContext` instance instead. Your code
130144
might look something like this::
131145

132146
return render_to_response('my_template.html',
133-
my_data_dictionary,
147+
my_context,
134148
context_instance=RequestContext(request))
135149

150+
.. deprecated:: 1.8
151+
152+
The ``context_instance`` argument is deprecated. Simply use ``context``.
153+
136154
``content_type``
137155
The MIME type to use for the resulting document. Defaults to the value of
138156
the :setting:`DEFAULT_CONTENT_TYPE` setting.
139157

158+
``status``
159+
The status code for the response. Defaults to ``200``.
160+
161+
.. versionchanged:: 1.8
162+
163+
The ``status`` parameter was added.
164+
140165
.. versionchanged:: 1.7
141166

142167
The ``dirs`` parameter was added.
143168

144-
.. versionchanged:: 1.8
169+
.. deprecated:: 1.8
145170

146171
The ``dirs`` parameter was deprecated.
147172

tests/context_processors/tests.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
from django.test import TestCase, override_settings
55

66

7-
@override_settings(ROOT_URLCONF='context_processors.urls')
7+
@override_settings(
8+
ROOT_URLCONF='context_processors.urls',
9+
TEMPLATE_CONTEXT_PROCESSORS=('django.template.context_processors.request',),
10+
)
811
class RequestContextProcessorTests(TestCase):
912
"""
1013
Tests for the ``django.template.context_processors.request`` processor.
@@ -35,7 +38,12 @@ def test_request_attributes(self):
3538
self.assertContains(response, url)
3639

3740

38-
@override_settings(ROOT_URLCONF='context_processors.urls', DEBUG=True, INTERNAL_IPS=('127.0.0.1',))
41+
@override_settings(
42+
DEBUG=True,
43+
INTERNAL_IPS=('127.0.0.1',),
44+
ROOT_URLCONF='context_processors.urls',
45+
TEMPLATE_CONTEXT_PROCESSORS=('django.template.context_processors.debug',),
46+
)
3947
class DebugContextProcessorTests(TestCase):
4048
"""
4149
Tests for the ``django.template.context_processors.debug`` processor.

0 commit comments

Comments
 (0)