django/django/template/backends/django.py
Aymeric Augustin f2c104ada6 Split DTL context creation into its own function.
This reduces the length of rope RequestContext gives users to hang
themselves with.

Thanks Alex Hill for the report and Tim Graham for the review.
2015-02-10 14:34:05 +01:00

74 lines
3 KiB
Python

# Since this package contains a "django" module, this is required on Python 2.
from __future__ import absolute_import
import warnings
from django.conf import settings
from django.template.context import Context, RequestContext, make_context
from django.template.engine import Engine, _dirs_undefined
from django.utils.deprecation import RemovedInDjango20Warning
from .base import BaseEngine
class DjangoTemplates(BaseEngine):
app_dirname = 'templates'
def __init__(self, params):
params = params.copy()
options = params.pop('OPTIONS').copy()
options.setdefault('debug', settings.TEMPLATE_DEBUG)
options.setdefault('file_charset', settings.FILE_CHARSET)
super(DjangoTemplates, self).__init__(params)
self.engine = Engine(self.dirs, self.app_dirs, **options)
def from_string(self, template_code):
return Template(self.engine.from_string(template_code))
def get_template(self, template_name, dirs=_dirs_undefined):
return Template(self.engine.get_template(template_name, dirs))
class Template(object):
def __init__(self, template):
self.template = template
@property
def origin(self):
# TODO: define the Origin API. For now simply forwarding to the
# underlying Template preserves backwards-compatibility.
return self.template.origin
def render(self, context=None, request=None):
# A deprecation path is required here to cover the following usage:
# >>> from django.template import Context
# >>> from django.template.loader import get_template
# >>> template = get_template('hello.html')
# >>> template.render(Context({'name': 'world'}))
# In Django 1.7 get_template() returned a django.template.Template.
# In Django 1.8 it returns a django.template.backends.django.Template.
# In Django 2.0 the isinstance checks should be removed. If passing a
# Context or a RequestContext works by accident, it won't be an issue
# per se, but it won't be officially supported either.
if isinstance(context, RequestContext):
if request is not None and request is not context.request:
raise ValueError(
"render() was called with a RequestContext and a request "
"argument which refer to different requests. Make sure "
"that the context argument is a dict or at least that "
"the two arguments refer to the same request.")
warnings.warn(
"render() must be called with a dict, not a RequestContext.",
RemovedInDjango20Warning, stacklevel=2)
elif isinstance(context, Context):
warnings.warn(
"render() must be called with a dict, not a Context.",
RemovedInDjango20Warning, stacklevel=2)
else:
context = make_context(context, request)
return self.template.render(context)