mirror of https://github.com/django/django.git
Encapsulated TEMPLATE_CONTEXT_PROCESSORS in Engine.
Since RequestContext doesn't know its Engine until it's passed to Template.render() -- and cannot without breaking a widely used public API -- an elaborate hack is required to apply context processors.
This commit is contained in:
parent
98ac69af53
commit
37505b6397
|
@ -1,8 +1,5 @@
|
|||
from copy import copy
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils import lru_cache
|
||||
from django.utils.module_loading import import_string
|
||||
|
||||
# Hard-coded processor for easier use of CSRF protection.
|
||||
_builtin_context_processors = ('django.core.context_processors.csrf',)
|
||||
|
@ -172,13 +169,6 @@ class RenderContext(BaseContext):
|
|||
return self.dicts[-1][key]
|
||||
|
||||
|
||||
@lru_cache.lru_cache()
|
||||
def get_standard_processors():
|
||||
context_processors = _builtin_context_processors
|
||||
context_processors += tuple(settings.TEMPLATE_CONTEXT_PROCESSORS)
|
||||
return tuple(import_string(path) for path in context_processors)
|
||||
|
||||
|
||||
class RequestContext(Context):
|
||||
"""
|
||||
This subclass of template.Context automatically populates itself using
|
||||
|
@ -190,11 +180,33 @@ class RequestContext(Context):
|
|||
use_l10n=None, use_tz=None, engine=None):
|
||||
Context.__init__(self, dict_, current_app=current_app,
|
||||
use_l10n=use_l10n, use_tz=use_tz, engine=engine)
|
||||
if processors is None:
|
||||
processors = ()
|
||||
else:
|
||||
processors = tuple(processors)
|
||||
updates = dict()
|
||||
for processor in get_standard_processors() + processors:
|
||||
updates.update(processor(request))
|
||||
self.update(updates)
|
||||
self._request = request
|
||||
self._processors = () if processors is None else tuple(processors)
|
||||
self._processors_index = len(self.dicts)
|
||||
self.update({}) # placeholder for context processors output
|
||||
self.engine = engine # re-run the setter in case engine is not None
|
||||
|
||||
@property
|
||||
def engine(self):
|
||||
return self._engine
|
||||
|
||||
@engine.setter
|
||||
def engine(self, engine):
|
||||
self._engine = engine
|
||||
if hasattr(self, '_processors_index'):
|
||||
if engine is None:
|
||||
# Unset context processors.
|
||||
self.dicts[self._processors_index] = {}
|
||||
else:
|
||||
# Set context processors for this engine.
|
||||
updates = {}
|
||||
for processor in engine.template_context_processors + self._processors:
|
||||
updates.update(processor(self._request))
|
||||
self.dicts[self._processors_index] = updates
|
||||
|
||||
def new(self, values=None):
|
||||
new_context = super(RequestContext, self).new(values)
|
||||
# This is for backwards-compatibility: RequestContexts created via
|
||||
# Context.new don't include values from context processors.
|
||||
del new_context._processors_index
|
||||
return new_context
|
||||
|
|
|
@ -9,6 +9,7 @@ from django.utils.functional import cached_property
|
|||
from django.utils.module_loading import import_string
|
||||
|
||||
from .base import Context, Lexer, Parser, Template, TemplateDoesNotExist
|
||||
from .context import _builtin_context_processors
|
||||
|
||||
|
||||
_dirs_undefined = object()
|
||||
|
@ -58,6 +59,12 @@ class Engine(object):
|
|||
file_charset=settings.FILE_CHARSET,
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def template_context_processors(self):
|
||||
context_processors = _builtin_context_processors
|
||||
context_processors += tuple(self.context_processors)
|
||||
return tuple(import_string(path) for path in context_processors)
|
||||
|
||||
@cached_property
|
||||
def template_loaders(self):
|
||||
return self.get_template_loaders(self.loaders)
|
||||
|
|
|
@ -91,13 +91,6 @@ def reset_default_template_engine(**kwargs):
|
|||
Engine.get_default.cache_clear()
|
||||
|
||||
|
||||
@receiver(setting_changed)
|
||||
def clear_context_processors_cache(**kwargs):
|
||||
if kwargs['setting'] == 'TEMPLATE_CONTEXT_PROCESSORS':
|
||||
from django.template.context import get_standard_processors
|
||||
get_standard_processors.cache_clear()
|
||||
|
||||
|
||||
@receiver(setting_changed)
|
||||
def clear_serializers_cache(**kwargs):
|
||||
if kwargs['setting'] == 'SERIALIZATION_MODULES':
|
||||
|
|
Loading…
Reference in New Issue