1
0
mirror of https://github.com/django/django.git synced 2025-05-11 17:36:28 +00:00
django/django/forms/renderers.py
William Schwartz 9ee693bd6c Fixed #32316 -- Deferred accessing __file__.
Deferred accessing the module-global variable __file__ because the
Python import API does not guarantee it always exists—in particular, it
does not exist in certain "frozen" environments. The following changes
advanced this goal.

Thanks to Carlton Gibson, Tom Forbes, Mariusz Felisiak, and Shreyas
Ravi for review and feedback.
2021-04-01 14:33:30 +02:00

66 lines
1.9 KiB
Python

import functools
from pathlib import Path
from django.conf import settings
from django.template.backends.django import DjangoTemplates
from django.template.loader import get_template
from django.utils.functional import cached_property
from django.utils.module_loading import import_string
@functools.lru_cache()
def get_default_renderer():
renderer_class = import_string(settings.FORM_RENDERER)
return renderer_class()
class BaseRenderer:
def get_template(self, template_name):
raise NotImplementedError('subclasses must implement get_template()')
def render(self, template_name, context, request=None):
template = self.get_template(template_name)
return template.render(context, request=request).strip()
class EngineMixin:
def get_template(self, template_name):
return self.engine.get_template(template_name)
@cached_property
def engine(self):
return self.backend({
'APP_DIRS': True,
'DIRS': [Path(__file__).parent / self.backend.app_dirname],
'NAME': 'djangoforms',
'OPTIONS': {},
})
class DjangoTemplates(EngineMixin, BaseRenderer):
"""
Load Django templates from the built-in widget templates in
django/forms/templates and from apps' 'templates' directory.
"""
backend = DjangoTemplates
class Jinja2(EngineMixin, BaseRenderer):
"""
Load Jinja2 templates from the built-in widget templates in
django/forms/jinja2 and from apps' 'jinja2' directory.
"""
@cached_property
def backend(self):
from django.template.backends.jinja2 import Jinja2
return Jinja2
class TemplatesSetting(BaseRenderer):
"""
Load templates using template.loader.get_template() which is configured
based on settings.TEMPLATES.
"""
def get_template(self, template_name):
return get_template(template_name)