1
0
mirror of https://github.com/django/django.git synced 2025-10-28 08:06:09 +00:00

Supported multiple template engines in render_to_string.

Adjusted its API through a deprecation path according to the DEP.
This commit is contained in:
Aymeric Augustin
2014-11-28 23:50:34 +01:00
parent f9a6ebf6f5
commit 90805b240f
7 changed files with 146 additions and 27 deletions

View File

@@ -12,6 +12,8 @@ from .base import Context, Lexer, Parser, Template, TemplateDoesNotExist
from .context import _builtin_context_processors
_context_instance_undefined = object()
_dictionary_undefined = object()
_dirs_undefined = object()
@@ -165,14 +167,22 @@ class Engine(object):
template = Template(template, origin, template_name, engine=self)
return template
def render_to_string(self, template_name, dictionary=None, context_instance=None,
dirs=_dirs_undefined):
def render_to_string(self, template_name, context=None,
context_instance=_context_instance_undefined,
dirs=_dirs_undefined,
dictionary=_dictionary_undefined):
"""
Loads the given template_name and renders it with the given dictionary as
context. The template_name may be a string to load a single template using
get_template, or it may be a tuple to use select_template to find one of
the templates in the list. Returns a string.
"""
if context_instance is _context_instance_undefined:
context_instance = None
else:
warnings.warn(
"The context_instance argument of render_to_string is "
"deprecated.", RemovedInDjango20Warning, stacklevel=2)
if dirs is _dirs_undefined:
# Do not set dirs to None here to avoid triggering the deprecation
# warning in select_template or get_template.
@@ -181,23 +191,30 @@ class Engine(object):
warnings.warn(
"The dirs argument of render_to_string is deprecated.",
RemovedInDjango20Warning, stacklevel=2)
if dictionary is _dictionary_undefined:
dictionary = None
else:
warnings.warn(
"The dictionary argument of render_to_string was renamed to "
"context.", RemovedInDjango20Warning, stacklevel=2)
context = dictionary
if isinstance(template_name, (list, tuple)):
t = self.select_template(template_name, dirs)
else:
t = self.get_template(template_name, dirs)
if not context_instance:
# Django < 1.8 accepted a Context in `dictionary` even though that's
# unintended. Preserve this ability but don't rewrap `dictionary`.
if isinstance(dictionary, Context):
return t.render(dictionary)
# 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(dictionary))
if not dictionary:
return t.render(Context(context))
if not context:
return t.render(context_instance)
# Add the dictionary to the context stack, ensuring it gets removed again
# 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(dictionary):
with context_instance.push(context):
return t.render(context_instance)
def select_template(self, template_name_list, dirs=_dirs_undefined):

View File

@@ -5,7 +5,8 @@ from django.utils.deprecation import RemovedInDjango20Warning
from . import engines
from .backends.django import DjangoTemplates
from .base import Origin, TemplateDoesNotExist
from .engine import _dirs_undefined, Engine
from .engine import (
_context_instance_undefined, _dictionary_undefined, _dirs_undefined)
class LoaderOrigin(Origin):
@@ -75,8 +76,61 @@ def select_template(template_name_list, dirs=_dirs_undefined, using=None):
raise TemplateDoesNotExist("No template names provided")
def render_to_string(*args, **kwargs):
return Engine.get_default().render_to_string(*args, **kwargs)
def render_to_string(template_name, context=None,
context_instance=_context_instance_undefined,
dirs=_dirs_undefined,
dictionary=_dictionary_undefined,
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 dirs is _dirs_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)
else:
# Some deprecated arguments were passed - use the legacy code path
for engine in _engine_list(using):
try:
# This is required for deprecating arguments specific to Django
# templates. Simply return engine.render_to_string(template_name,
# context) in Django 2.0.
if isinstance(engine, DjangoTemplates):
# Hack -- use the internal Engine instance of DjangoTemplates.
return engine.engine.render_to_string(
template_name, context, context_instance, dirs, 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 dirs is not _dirs_undefined:
warnings.warn(
"Skipping template backend %s because its render_to_string "
"method doesn't support the dirs 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:
continue
if template_name:
if isinstance(template_name, (list, tuple)):
template_name = ', '.join(template_name)
raise TemplateDoesNotExist(template_name)
else:
raise TemplateDoesNotExist("No template names provided")
def _engine_list(using=None):