diff --git a/django/shortcuts.py b/django/shortcuts.py index 8ff39c08ba..b5f20b832c 100644 --- a/django/shortcuts.py +++ b/django/shortcuts.py @@ -10,63 +10,27 @@ from django.db.models.query import QuerySet from django.http import ( Http404, HttpResponse, HttpResponsePermanentRedirect, HttpResponseRedirect, ) -from django.template import RequestContext, loader -from django.template.engine import ( - _context_instance_undefined, _dictionary_undefined -) +from django.template import loader from django.utils import six from django.utils.encoding import force_text from django.utils.functional import Promise -def render_to_response(template_name, context=None, - context_instance=_context_instance_undefined, - content_type=None, status=None, - dictionary=_dictionary_undefined, using=None): +def render_to_response(template_name, context=None, content_type=None, status=None, using=None): """ Returns a HttpResponse whose content is filled with the result of calling django.template.loader.render_to_string() with the passed arguments. """ - if (context_instance is _context_instance_undefined - and dictionary is _dictionary_undefined): - # No deprecated arguments were passed - use the new code path - content = loader.render_to_string(template_name, context, using=using) - - else: - # Some deprecated arguments were passed - use the legacy code path - content = loader.render_to_string( - template_name, context, context_instance, dictionary, - using=using) - + content = loader.render_to_string(template_name, context, using=using) return HttpResponse(content, content_type, status) -def render(request, template_name, context=None, - context_instance=_context_instance_undefined, - content_type=None, status=None, - dictionary=_dictionary_undefined, - using=None): +def render(request, template_name, context=None, content_type=None, status=None, using=None): """ Returns a HttpResponse whose content is filled with the result of calling django.template.loader.render_to_string() with the passed arguments. - Uses a RequestContext by default. """ - if (context_instance is _context_instance_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: - pass - else: - context_instance = RequestContext(request) - content = loader.render_to_string( - template_name, context, context_instance, dictionary, - using=using) - + content = loader.render_to_string(template_name, context, request, using=using) return HttpResponse(content, content_type, status) diff --git a/django/template/engine.py b/django/template/engine.py index 2761a70400..ec89b8d7ef 100644 --- a/django/template/engine.py +++ b/django/template/engine.py @@ -11,9 +11,6 @@ from .context import _builtin_context_processors from .exceptions import TemplateDoesNotExist from .library import import_library -_context_instance_undefined = object() -_dictionary_undefined = object() - class Engine(object): default_builtins = [ @@ -183,40 +180,17 @@ class Engine(object): # will be removed in Django 1.10. It's superseded by a new render_to_string # function in django.template.loader. - def render_to_string(self, template_name, context=None, - context_instance=_context_instance_undefined, - dictionary=_dictionary_undefined): - if context_instance is _context_instance_undefined: - context_instance = None - else: - warnings.warn( - "The context_instance argument of render_to_string is " - "deprecated.", RemovedInDjango110Warning, stacklevel=2) - if dictionary is _dictionary_undefined: - dictionary = None - else: - warnings.warn( - "The dictionary argument of render_to_string was renamed to " - "context.", RemovedInDjango110Warning, stacklevel=2) - context = dictionary - + def render_to_string(self, template_name, context=None): if isinstance(template_name, (list, tuple)): t = self.select_template(template_name) else: t = self.get_template(template_name) - if not context_instance: - # Django < 1.8 accepted a Context in `context` even though that's - # unintended. Preserve this ability but don't rewrap `context`. - if isinstance(context, Context): - return t.render(context) - else: - return t.render(Context(context)) - if not context: - return t.render(context_instance) - # Add the context to the context stack, ensuring it gets removed again - # to keep the context_instance in the same state it started in. - with context_instance.push(context): - return t.render(context_instance) + # Django < 1.8 accepted a Context in `context` even though that's + # unintended. Preserve this ability but don't rewrap `context`. + if isinstance(context, Context): + return t.render(context) + else: + return t.render(Context(context)) def select_template(self, template_name_list): """ diff --git a/django/template/loader.py b/django/template/loader.py index d0ac9f6494..83ac24d6c8 100644 --- a/django/template/loader.py +++ b/django/template/loader.py @@ -3,8 +3,6 @@ import warnings from django.utils.deprecation import RemovedInDjango110Warning from . import engines -from .backends.django import DjangoTemplates -from .engine import _context_instance_undefined, _dictionary_undefined from .exceptions import TemplateDoesNotExist from .loaders import base @@ -49,60 +47,17 @@ def select_template(template_name_list, using=None): raise TemplateDoesNotExist("No template names provided") -def render_to_string(template_name, context=None, - context_instance=_context_instance_undefined, - dictionary=_dictionary_undefined, - request=None, using=None): +def render_to_string(template_name, context=None, request=None, using=None): """ Loads a template and renders it with a context. Returns a string. template_name may be a string or a list of strings. """ - if (context_instance is _context_instance_undefined - and dictionary is _dictionary_undefined): - # No deprecated arguments were passed - use the new code path - if isinstance(template_name, (list, tuple)): - template = select_template(template_name, using=using) - else: - template = get_template(template_name, using=using) - return template.render(context, request) - + if isinstance(template_name, (list, tuple)): + template = select_template(template_name, using=using) else: - chain = [] - # Some deprecated arguments were passed - use the legacy code path - for engine in _engine_list(using): - try: - # This is required for deprecating properly arguments specific - # to Django templates. Remove Engine.render_to_string() at the - # same time as this code path in Django 1.10. - if isinstance(engine, DjangoTemplates): - if request is not None: - raise ValueError( - "render_to_string doesn't support the request argument " - "when some deprecated arguments are passed.") - # Hack -- use the internal Engine instance of DjangoTemplates. - return engine.engine.render_to_string( - template_name, context, context_instance, dictionary) - elif context_instance is not _context_instance_undefined: - warnings.warn( - "Skipping template backend %s because its render_to_string " - "method doesn't support the context_instance argument." % - engine.name, stacklevel=2) - elif dictionary is not _dictionary_undefined: - warnings.warn( - "Skipping template backend %s because its render_to_string " - "method doesn't support the dictionary argument." % - engine.name, stacklevel=2) - except TemplateDoesNotExist as e: - chain.append(e) - continue - - if template_name: - if isinstance(template_name, (list, tuple)): - template_name = ', '.join(template_name) - raise TemplateDoesNotExist(template_name, chain=chain) - else: - raise TemplateDoesNotExist("No template names provided") + template = get_template(template_name, using=using) + return template.render(context, request) def _engine_list(using=None): diff --git a/docs/topics/http/shortcuts.txt b/docs/topics/http/shortcuts.txt index 03562aaf89..4ed7159de6 100644 --- a/docs/topics/http/shortcuts.txt +++ b/docs/topics/http/shortcuts.txt @@ -15,14 +15,13 @@ 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, using=None) +.. function:: render(request, template_name, context=None, content_type=None, status=None, using=None) Combines a given template with a given context dictionary and returns an :class:`~django.http.HttpResponse` object with that rendered text. - :func:`render()` is the same as a call to - :func:`render_to_response()` with a ``context_instance`` argument that - forces the use of a :class:`~django.template.RequestContext`. + :func:`render()` is the same as a call to :func:`render_to_response()` but + it also makes the current request available in the template. Django does not provide a shortcut function which returns a :class:`~django.template.response.TemplateResponse` because the constructor @@ -46,20 +45,6 @@ Optional arguments is an empty dictionary. If a value in the dictionary is callable, the view will call it just before rendering the template. - .. versionchanged:: 1.8 - - The ``context`` argument used to be called ``dictionary``. That name - is deprecated in Django 1.8 and will be removed in Django 1.10. - -``context_instance`` - The context instance to render the template with. By default, the template - will be rendered with a ``RequestContext`` instance (filled with values from - ``request`` and ``context``). - - .. deprecated:: 1.8 - - The ``context_instance`` argument is deprecated. Simply use ``context``. - ``content_type`` The MIME type to use for the resulting document. Defaults to the value of the :setting:`DEFAULT_CONTENT_TYPE` setting. @@ -103,7 +88,7 @@ This example is equivalent to:: ``render_to_response`` ====================== -.. function:: render_to_response(template_name, context=None, context_instance=_context_instance_undefined, content_type=None, status=None, using=None) +.. function:: render_to_response(template_name, context=None, content_type=None, status=None, using=None) Renders a given template with a given context dictionary and returns an :class:`~django.http.HttpResponse` object with that rendered text. @@ -125,27 +110,6 @@ Optional arguments is an empty dictionary. If a value in the dictionary is callable, the view will call it just before rendering the template. - .. versionchanged:: 1.8 - - The ``context`` argument used to be called ``dictionary``. That name - is deprecated in Django 1.8 and will be removed in Django 1.10. - -``context_instance`` - The context instance to render the template with. By default, the template - will be rendered with a :class:`~django.template.Context` instance (filled - with values from ``context``). If you need to use :ref:`context - processors `, render the template with - a :class:`~django.template.RequestContext` instance instead. Your code - might look something like this:: - - return render_to_response('my_template.html', - my_context, - context_instance=RequestContext(request)) - - .. deprecated:: 1.8 - - The ``context_instance`` argument is deprecated. Simply use ``context``. - ``content_type`` The MIME type to use for the resulting document. Defaults to the value of the :setting:`DEFAULT_CONTENT_TYPE` setting. diff --git a/docs/topics/templates.txt b/docs/topics/templates.txt index b8a537aa5d..af165b7052 100644 --- a/docs/topics/templates.txt +++ b/docs/topics/templates.txt @@ -261,7 +261,7 @@ the following templates: In addition, to cut down on the repetitive nature of loading and rendering templates, Django provides a shortcut function which automates the process. -.. function:: render_to_string(template_name, context=None, context_instance=_context_instance_undefined, request=None, using=None) +.. function:: render_to_string(template_name, context=None, request=None, using=None) ``render_to_string()`` loads a template like :func:`get_template` and calls its ``render()`` method immediately. It takes the following @@ -275,24 +275,6 @@ templates, Django provides a shortcut function which automates the process. ``context`` A :class:`dict` to be used as the template's context for rendering. - .. versionchanged:: 1.8 - - The ``context`` argument used to be called ``dictionary``. That name - is deprecated in Django 1.8 and will be removed in Django 1.10. - - ``context`` is now optional. An empty context will be used if it - isn't provided. - - ``context_instance`` - An instance of :class:`~django.template.Context` or a subclass (e.g., an - instance of :class:`~django.template.RequestContext`) to use as the - template's context. - - .. deprecated:: 1.8 - - The ``context_instance`` argument is deprecated. Use ``context`` and - if needed ``request``. - ``request`` An optional :class:`~django.http.HttpRequest` that will be available during the template's rendering process. diff --git a/tests/shortcuts/tests.py b/tests/shortcuts/tests.py index 9418424922..9712858c70 100644 --- a/tests/shortcuts/tests.py +++ b/tests/shortcuts/tests.py @@ -19,13 +19,6 @@ class ShortcutTests(SimpleTestCase): self.assertEqual(response.status_code, 200) self.assertEqual(response.content, b'FOO.BAR..\n') - @ignore_warnings(category=RemovedInDjango110Warning) - def test_render_to_response_with_request_context(self): - response = self.client.get('/render_to_response/request_context/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, b'FOO.BAR../render_to_response/request_context/\n') - self.assertEqual(response['Content-Type'], 'text/html; charset=utf-8') - def test_render_to_response_with_content_type(self): response = self.client.get('/render_to_response/content_type/') self.assertEqual(response.status_code, 200) @@ -68,13 +61,6 @@ class ShortcutTests(SimpleTestCase): self.assertEqual(response.status_code, 200) self.assertEqual(response.content, b'FOO.BAR../render/multiple_templates/\n') - @ignore_warnings(category=RemovedInDjango110Warning) - def test_render_with_base_context(self): - response = self.client.get('/render/base_context/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.content, b'FOO.BAR..\n') - self.assertEqual(response['Content-Type'], 'text/html; charset=utf-8') - def test_render_with_content_type(self): response = self.client.get('/render/content_type/') self.assertEqual(response.status_code, 200) diff --git a/tests/shortcuts/urls.py b/tests/shortcuts/urls.py index 0c01ada37a..d3d68e3b29 100644 --- a/tests/shortcuts/urls.py +++ b/tests/shortcuts/urls.py @@ -5,14 +5,12 @@ from . import views urlpatterns = [ url(r'^render_to_response/$', views.render_to_response_view), url(r'^render_to_response/multiple_templates/$', views.render_to_response_view_with_multiple_templates), - url(r'^render_to_response/request_context/$', views.render_to_response_view_with_request_context), url(r'^render_to_response/content_type/$', views.render_to_response_view_with_content_type), url(r'^render_to_response/status/$', views.render_to_response_view_with_status), url(r'^render_to_response/using/$', views.render_to_response_view_with_using), url(r'^render_to_response/context_instance_misuse/$', views.render_to_response_with_context_instance_misuse), url(r'^render/$', views.render_view), url(r'^render/multiple_templates/$', views.render_view_with_multiple_templates), - url(r'^render/base_context/$', views.render_view_with_base_context), url(r'^render/content_type/$', views.render_view_with_content_type), url(r'^render/status/$', views.render_view_with_status), url(r'^render/using/$', views.render_view_with_using), diff --git a/tests/shortcuts/views.py b/tests/shortcuts/views.py index e072e96b32..edacb23938 100644 --- a/tests/shortcuts/views.py +++ b/tests/shortcuts/views.py @@ -1,5 +1,5 @@ from django.shortcuts import render, render_to_response -from django.template import Context, RequestContext +from django.template import RequestContext def render_to_response_view(request): @@ -19,13 +19,6 @@ def render_to_response_view_with_multiple_templates(request): }) -def render_to_response_view_with_request_context(request): - return render_to_response('shortcuts/render_test.html', { - 'foo': 'FOO', - 'bar': 'BAR', - }, context_instance=RequestContext(request)) - - def render_to_response_view_with_content_type(request): return render_to_response('shortcuts/render_test.html', { 'foo': 'FOO', @@ -72,13 +65,6 @@ def render_view_with_multiple_templates(request): }) -def render_view_with_base_context(request): - return render(request, 'shortcuts/render_test.html', { - 'foo': 'FOO', - 'bar': 'BAR', - }, context_instance=Context()) - - def render_view_with_content_type(request): return render(request, 'shortcuts/render_test.html', { 'foo': 'FOO', diff --git a/tests/template_tests/test_engine.py b/tests/template_tests/test_engine.py index d2c45b25a9..61ab7259ea 100644 --- a/tests/template_tests/test_engine.py +++ b/tests/template_tests/test_engine.py @@ -2,22 +2,17 @@ import os from django.template import Context from django.template.engine import Engine -from django.test import SimpleTestCase, ignore_warnings -from django.utils.deprecation import RemovedInDjango110Warning +from django.test import SimpleTestCase from .utils import ROOT, TEMPLATE_DIR OTHER_DIR = os.path.join(ROOT, 'other_templates') -@ignore_warnings(category=RemovedInDjango110Warning) -class DeprecatedRenderToStringTest(SimpleTestCase): +class RenderToStringTest(SimpleTestCase): def setUp(self): - self.engine = Engine( - dirs=[TEMPLATE_DIR], - libraries={'custom': 'template_tests.templatetags.custom'}, - ) + self.engine = Engine(dirs=[TEMPLATE_DIR]) def test_basic_context(self): self.assertEqual( @@ -25,33 +20,6 @@ class DeprecatedRenderToStringTest(SimpleTestCase): 'obj:test\n', ) - def test_existing_context_kept_clean(self): - context = Context({'obj': 'before'}) - output = self.engine.render_to_string( - 'test_context.html', {'obj': 'after'}, context_instance=context, - ) - self.assertEqual(output, 'obj:after\n') - self.assertEqual(context['obj'], 'before') - - def test_no_empty_dict_pushed_to_stack(self): - """ - #21741 -- An empty dict should not be pushed to the context stack when - render_to_string is called without a context argument. - """ - - # The stack should have a length of 1, corresponding to the builtins - self.assertEqual( - '1', - self.engine.render_to_string('test_context_stack.html').strip(), - ) - self.assertEqual( - '1', - self.engine.render_to_string( - 'test_context_stack.html', - context_instance=Context() - ).strip(), - ) - class LoaderTests(SimpleTestCase): diff --git a/tests/test_client_regress/tests.py b/tests/test_client_regress/tests.py index 500c28f9ae..0e0892e4e4 100644 --- a/tests/test_client_regress/tests.py +++ b/tests/test_client_regress/tests.py @@ -20,9 +20,7 @@ from django.test import ( from django.test.client import RedirectCycleError, RequestFactory, encode_file from django.test.utils import ContextList, str_prefix from django.utils._os import upath -from django.utils.deprecation import ( - RemovedInDjango20Warning, RemovedInDjango110Warning, -) +from django.utils.deprecation import RemovedInDjango20Warning from django.utils.translation import ugettext_lazy from .models import CustomUser @@ -1064,7 +1062,6 @@ class ContextTests(TestDataMixin, TestCase): 'python', 'dolly'}, l.keys()) - @ignore_warnings(category=RemovedInDjango110Warning) def test_15368(self): # Need to insert a context processor that assumes certain things about # the request instance. This triggers a bug caused by some ways of diff --git a/tests/test_client_regress/views.py b/tests/test_client_regress/views.py index 6ba419833a..8470bb9935 100644 --- a/tests/test_client_regress/views.py +++ b/tests/test_client_regress/views.py @@ -4,8 +4,7 @@ from django.conf import settings from django.contrib.auth.decorators import login_required from django.core.serializers.json import DjangoJSONEncoder from django.http import HttpResponse, HttpResponseRedirect, JsonResponse -from django.shortcuts import render_to_response -from django.template import RequestContext +from django.shortcuts import render, render_to_response from django.template.loader import render_to_string from django.test import Client from django.test.client import CONTENT_TYPE_RE @@ -152,7 +151,7 @@ def read_buffer(request): def request_context_view(request): # Special attribute that won't be present on a plain HttpRequest request.special_path = request.path - return render_to_response('request_context.html', context_instance=RequestContext(request, {})) + return render(request, 'request_context.html') def render_template_multiple_times(request):