From 802ee5d0ea234d86fbcd7875a15f3b8a47c02967 Mon Sep 17 00:00:00 2001 From: Andrei Fokau Date: Wed, 18 Nov 2015 15:25:58 +0100 Subject: [PATCH] Fix template.render deprecation warnings for 1.9+ --- rest_framework/compat.py | 24 +++++++++++++++ rest_framework/filters.py | 20 ++++++------- rest_framework/pagination.py | 15 +++++----- rest_framework/renderers.py | 30 +++++++++---------- rest_framework/templatetags/rest_framework.py | 11 +++---- 5 files changed, 62 insertions(+), 38 deletions(-) diff --git a/rest_framework/compat.py b/rest_framework/compat.py index 8b782a1c2..c6966a980 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -9,6 +9,7 @@ from __future__ import unicode_literals import django from django.conf import settings from django.db import connection, transaction +from django.template import Context, RequestContext, Template from django.utils import six from django.views.generic import View @@ -191,6 +192,7 @@ try: except ImportError: DecimalValidator = None + def set_rollback(): if hasattr(transaction, 'set_rollback'): if connection.settings_dict.get('ATOMIC_REQUESTS', False): @@ -206,3 +208,25 @@ def set_rollback(): else: # transaction not managed pass + + +def template_render(template, context=None, request=None): + """ + Passing Context or RequestContext to Template.render is deprecated in 1.9+, + see https://github.com/django/django/pull/3883 and + https://github.com/django/django/blob/1.9rc1/django/template/backends/django.py#L82-L84 + + :param template: Template instance + :param context: dict + :param request: Request instance + :return: rendered template as SafeText instance + """ + if django.VERSION < (1, 9) or isinstance(template, Template): + if request: + context = RequestContext(request, context) + else: + context = Context(context) + return template.render(context) + # backends template, e.g. django.template.backends.django.Template + else: + return template.render(context, request=request) diff --git a/rest_framework/filters.py b/rest_framework/filters.py index a62139405..66f1185a3 100644 --- a/rest_framework/filters.py +++ b/rest_framework/filters.py @@ -10,12 +10,12 @@ from functools import reduce from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.db import models -from django.template import Context, loader +from django.template import loader from django.utils import six from django.utils.translation import ugettext_lazy as _ from rest_framework.compat import ( - crispy_forms, distinct, django_filters, guardian + crispy_forms, distinct, django_filters, guardian, template_render ) from rest_framework.settings import api_settings @@ -122,11 +122,11 @@ class DjangoFilterBackend(BaseFilterBackend): filter_instance = filter_class(request.query_params, queryset=queryset) else: filter_instance = None - context = Context({ + context = { 'filter': filter_instance - }) + } template = loader.get_template(self.template) - return template.render(context) + return template_render(template, context) class SearchFilter(BaseFilterBackend): @@ -185,12 +185,12 @@ class SearchFilter(BaseFilterBackend): term = self.get_search_terms(request) term = term[0] if term else '' - context = Context({ + context = { 'param': self.search_param, 'term': term - }) + } template = loader.get_template(self.template) - return template.render(context) + return template_render(template, context) class OrderingFilter(BaseFilterBackend): @@ -284,8 +284,8 @@ class OrderingFilter(BaseFilterBackend): def to_html(self, request, queryset, view): template = loader.get_template(self.template) - context = Context(self.get_template_context(request, queryset, view)) - return template.render(context) + context = self.get_template_context(request, queryset, view) + return template_render(template, context) class DjangoObjectPermissionsFilter(BaseFilterBackend): diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py index fc7b90967..7f9c135fc 100644 --- a/rest_framework/pagination.py +++ b/rest_framework/pagination.py @@ -10,11 +10,12 @@ from collections import OrderedDict, namedtuple from django.core.paginator import Paginator as DjangoPaginator from django.core.paginator import InvalidPage -from django.template import Context, loader +from django.template import loader from django.utils import six from django.utils.six.moves.urllib import parse as urlparse from django.utils.translation import ugettext_lazy as _ +from rest_framework.compat import template_render from rest_framework.exceptions import NotFound from rest_framework.response import Response from rest_framework.settings import api_settings @@ -273,8 +274,8 @@ class PageNumberPagination(BasePagination): def to_html(self): template = loader.get_template(self.template) - context = Context(self.get_html_context()) - return template.render(context) + context = self.get_html_context() + return template_render(template, context) class LimitOffsetPagination(BasePagination): @@ -389,8 +390,8 @@ class LimitOffsetPagination(BasePagination): def to_html(self): template = loader.get_template(self.template) - context = Context(self.get_html_context()) - return template.render(context) + context = self.get_html_context() + return template_render(template, context) class CursorPagination(BasePagination): @@ -692,5 +693,5 @@ class CursorPagination(BasePagination): def to_html(self): template = loader.get_template(self.template) - context = Context(self.get_html_context()) - return template.render(context) + context = self.get_html_context() + return template_render(template, context) diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index ba4d60881..8eb6725d5 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -15,13 +15,13 @@ from django import forms from django.core.exceptions import ImproperlyConfigured from django.core.paginator import Page from django.http.multipartparser import parse_header -from django.template import Context, RequestContext, Template, loader +from django.template import Template, loader from django.test.client import encode_multipart from django.utils import six from rest_framework import VERSION, exceptions, serializers, status from rest_framework.compat import ( - INDENT_SEPARATORS, LONG_SEPARATORS, SHORT_SEPARATORS + INDENT_SEPARATORS, LONG_SEPARATORS, SHORT_SEPARATORS, template_render ) from rest_framework.exceptions import ParseError from rest_framework.request import is_form_media_type, override_method @@ -168,7 +168,7 @@ class TemplateHTMLRenderer(BaseRenderer): template = self.resolve_template(template_names) context = self.resolve_context(data, request, response) - return template.render(context) + return template_render(template, context, request=request) def resolve_template(self, template_names): return loader.select_template(template_names) @@ -176,7 +176,7 @@ class TemplateHTMLRenderer(BaseRenderer): def resolve_context(self, data, request, response): if response.exception: data['status_code'] = response.status_code - return RequestContext(request, data) + return data def get_template_names(self, response, view): if response.template_name: @@ -230,7 +230,7 @@ class StaticHTMLRenderer(TemplateHTMLRenderer): request = renderer_context['request'] template = self.get_exception_template(response) context = self.resolve_context(data, request, response) - return template.render(context) + return template_render(template, context, request=request) return data @@ -333,8 +333,8 @@ class HTMLFormRenderer(BaseRenderer): template_name = style['template_pack'].strip('/') + '/' + style['base_template'] template = loader.get_template(template_name) - context = Context({'field': field, 'style': style}) - return template.render(context) + context = {'field': field, 'style': style} + return template_render(template, context) def render(self, data, accepted_media_type=None, renderer_context=None): """ @@ -350,11 +350,11 @@ class HTMLFormRenderer(BaseRenderer): template_pack = style['template_pack'].strip('/') template_name = template_pack + '/' + self.base_template template = loader.get_template(template_name) - context = Context({ + context = { 'form': form, 'style': style - }) - return template.render(context) + } + return template_render(template, context) class BrowsableAPIRenderer(BaseRenderer): @@ -600,8 +600,8 @@ class BrowsableAPIRenderer(BaseRenderer): return template = loader.get_template(self.filter_template) - context = Context({'elements': elements}) - return template.render(context) + context = {'elements': elements} + return template_render(template, context) def get_context(self, data, accepted_media_type, renderer_context): """ @@ -672,8 +672,7 @@ class BrowsableAPIRenderer(BaseRenderer): template = loader.get_template(self.template) context = self.get_context(data, accepted_media_type, renderer_context) - context = RequestContext(renderer_context['request'], context) - ret = template.render(context) + ret = template_render(template, context, request=renderer_context['request']) # Munge DELETE Response code to allow us to return content # (Do this *after* we've rendered the template so that we include @@ -709,8 +708,7 @@ class AdminRenderer(BrowsableAPIRenderer): template = loader.get_template(self.template) context = self.get_context(data, accepted_media_type, renderer_context) - context = RequestContext(renderer_context['request'], context) - ret = template.render(context) + ret = template_render(template, context, request=renderer_context['request']) # Creation and deletion should use redirects in the admin style. if (response.status_code == status.HTTP_201_CREATED) and ('Location' in response): diff --git a/rest_framework/templatetags/rest_framework.py b/rest_framework/templatetags/rest_framework.py index 482e92470..05a7ce04f 100644 --- a/rest_framework/templatetags/rest_framework.py +++ b/rest_framework/templatetags/rest_framework.py @@ -4,12 +4,13 @@ import re from django import template from django.core.urlresolvers import NoReverseMatch, reverse -from django.template import Context, loader +from django.template import loader from django.utils import six from django.utils.encoding import force_text, iri_to_uri from django.utils.html import escape, format_html, smart_urlquote from django.utils.safestring import SafeData, mark_safe +from rest_framework.compat import template_render from rest_framework.renderers import HTMLFormRenderer from rest_framework.utils.urls import replace_query_param @@ -128,12 +129,12 @@ def format_value(value): template = loader.get_template('rest_framework/admin/list_value.html') else: template = loader.get_template('rest_framework/admin/simple_list_value.html') - context = Context({'value': value}) - return template.render(context) + context = {'value': value} + return template_render(template, context) elif isinstance(value, dict): template = loader.get_template('rest_framework/admin/dict_value.html') - context = Context({'value': value}) - return template.render(context) + context = {'value': value} + return template_render(template, context) elif isinstance(value, six.string_types): if ( (value.startswith('http:') or value.startswith('https:')) and not