Commit 9af3c6b9 authored by Tim Graham's avatar Tim Graham
Browse files

Made template response APIs enforce the use of dict and backend-specific template objects.

Per deprecation timeline; refs 79deb6a0.
parent e6cfa08f
Loading
Loading
Loading
Loading
+2 −53
Original line number Diff line number Diff line
import warnings

from django.http import HttpResponse
from django.utils import six
from django.utils.deprecation import RemovedInDjango110Warning

from .backends.django import Template as BackendTemplate
from .base import Template
from .context import Context, RequestContext
from .loader import get_template, select_template


@@ -19,14 +13,6 @@ class SimpleTemplateResponse(HttpResponse):

    def __init__(self, template, context=None, content_type=None, status=None,
                 charset=None, using=None):
        if isinstance(template, Template):
            warnings.warn(
                "{}'s template argument cannot be a django.template.Template "
                "anymore. It may be a backend-specific template like those "
                "created by get_template().".format(self.__class__.__name__),
                RemovedInDjango110Warning, stacklevel=2)
            template = BackendTemplate(template)

        # It would seem obvious to call these next two members 'template' and
        # 'context', but those names are reserved as part of the test Client
        # API. To avoid the name collision, we use different names.
@@ -83,46 +69,9 @@ class SimpleTemplateResponse(HttpResponse):
        else:
            return template

    def _resolve_template(self, template):
        # This wrapper deprecates returning a django.template.Template in
        # subclasses that override resolve_template. It can be removed in
        # Django 1.10.
        new_template = self.resolve_template(template)
        if isinstance(new_template, Template):
            warnings.warn(
                "{}.resolve_template() must return a backend-specific "
                "template like those created by get_template(), not a "
                "{}.".format(
                    self.__class__.__name__, new_template.__class__.__name__),
                RemovedInDjango110Warning, stacklevel=2)
            new_template = BackendTemplate(new_template)
        return new_template

    def resolve_context(self, context):
        return context

    def _resolve_context(self, context):
        # This wrapper deprecates returning a Context or a RequestContext in
        # subclasses that override resolve_context. It can be removed in
        # Django 1.10. If returning a Context or a RequestContext works by
        # accident, it won't be an issue per se, but it won't be officially
        # supported either.
        new_context = self.resolve_context(context)
        if isinstance(new_context, RequestContext) and self._request is None:
            self._request = new_context.request
        if isinstance(new_context, Context):
            warnings.warn(
                "{}.resolve_context() must return a dict, not a {}.".format(
                    self.__class__.__name__, new_context.__class__.__name__),
                RemovedInDjango110Warning, stacklevel=2)
            # It would be tempting to do new_context = new_context.flatten()
            # here but that would cause template context processors to run for
            # TemplateResponse(request, template, Context({})), which would be
            # backwards-incompatible. As a consequence another deprecation
            # warning will be raised when rendering the template. There isn't
            # much we can do about that.
        return new_context

    @property
    def rendered_content(self):
        """Returns the freshly rendered content for the template and context
@@ -132,8 +81,8 @@ class SimpleTemplateResponse(HttpResponse):
        response content, you must either call render(), or set the
        content explicitly using the value of this property.
        """
        template = self._resolve_template(self.template_name)
        context = self._resolve_context(self.context_data)
        template = self.resolve_template(self.template_name)
        context = self.resolve_context(self.context_data)
        content = template.render(context, self._request)
        return content

+0 −44
Original line number Diff line number Diff line
@@ -38,10 +38,6 @@ Attributes

    Example: ``['foo.html', 'path/to/bar.html']``

    .. deprecated:: 1.8

        ``template_name`` used to accept a :class:`~django.template.Template`.

.. attribute:: SimpleTemplateResponse.context_data

    The context data to be used when rendering the template. It must be a
@@ -49,10 +45,6 @@ Attributes

    Example: ``{'foo': 123}``

    .. deprecated:: 1.8

        ``context_data`` used to accept a :class:`~django.template.Context`.

.. attribute:: SimpleTemplateResponse.rendered_content

    The current rendered value of the response content, using the current
@@ -76,18 +68,10 @@ Methods
        :func:`~django.template.loader.get_template()`), the name of a template,
        or a list of template names.

        .. deprecated:: 1.8

            ``template`` used to accept a :class:`~django.template.Template`.

    ``context``
        A :class:`dict` of values to add to the template context. By default,
        this is an empty dictionary.

        .. deprecated:: 1.8

            ``context`` used to accept a :class:`~django.template.Context`.

    ``content_type``
        The value included in the HTTP ``Content-Type`` header, including the
        MIME type specification and the character set encoding. If
@@ -118,16 +102,6 @@ Methods

    Override this method in order to customize the context.

    .. versionchanged:: 1.8

        ``resolve_context`` returns a :class:`dict`. It used to return a
        :class:`~django.template.Context`.

    .. deprecated:: 1.8

        ``resolve_context`` no longer accepts a
        :class:`~django.template.Context`.

.. method:: SimpleTemplateResponse.resolve_template(template)

    Resolves the template instance to use for rendering. Accepts a
@@ -139,16 +113,6 @@ Methods

    Override this method in order to customize template loading.

    .. versionchanged:: 1.8

        ``resolve_template`` returns backend-dependent template object. It
        used to return a :class:`~django.template.Template`.

    .. deprecated:: 1.8

        ``resolve_template`` no longer accepts a
        :class:`~django.template.Template`.

.. method:: SimpleTemplateResponse.add_post_render_callback()

    Add a callback that will be invoked after rendering has taken
@@ -203,18 +167,10 @@ Methods
        :func:`~django.template.loader.get_template()`), the name of a template,
        or a list of template names.

        .. deprecated:: 1.8

            ``template`` used to accept a :class:`~django.template.Template`.

    ``context``
        A :class:`dict` of values to add to the template context. By default,
        this is an empty dictionary.

        .. deprecated:: 1.8

            ``context`` used to accept a :class:`~django.template.Context`.

    ``content_type``
        The value included in the HTTP ``Content-Type`` header, including the
        MIME type specification and the character set encoding. If
+2 −13
Original line number Diff line number Diff line
@@ -5,15 +5,12 @@ import time
from datetime import datetime

from django.conf import settings
from django.template import Context, engines
from django.template import engines
from django.template.response import (
    ContentNotRenderedError, SimpleTemplateResponse, TemplateResponse,
)
from django.test import (
    RequestFactory, SimpleTestCase, ignore_warnings, override_settings,
)
from django.test import RequestFactory, SimpleTestCase, override_settings
from django.test.utils import require_jinja2
from django.utils.deprecation import RemovedInDjango110Warning

from .utils import TEMPLATE_DIR

@@ -118,14 +115,6 @@ class SimpleTemplateResponseTest(SimpleTestCase):
        response.render()
        self.assertEqual(response.content, b'bar')

    @ignore_warnings(category=RemovedInDjango110Warning)
    def test_context_instance(self):
        response = self._response('{{ foo }}{{ processors }}',
                                  Context({'foo': 'bar'}))
        self.assertEqual(response.context_data.__class__, Context)
        response.render()
        self.assertEqual(response.content, b'bar')

    def test_kwargs(self):
        response = self._response(content_type='application/json', status=504)
        self.assertEqual(response['content-type'], 'application/json')