renderers.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import functools
  2. from pathlib import Path
  3. from django.conf import settings
  4. from django.template.backends.django import DjangoTemplates
  5. from django.template.loader import get_template
  6. from django.utils.functional import cached_property
  7. from django.utils.module_loading import import_string
  8. @functools.lru_cache
  9. def get_default_renderer():
  10. renderer_class = import_string(settings.FORM_RENDERER)
  11. return renderer_class()
  12. class BaseRenderer:
  13. form_template_name = "django/forms/div.html"
  14. formset_template_name = "django/forms/formsets/div.html"
  15. field_template_name = "django/forms/field.html"
  16. bound_field_class = None
  17. def get_template(self, template_name):
  18. raise NotImplementedError("subclasses must implement get_template()")
  19. def render(self, template_name, context, request=None):
  20. template = self.get_template(template_name)
  21. return template.render(context, request=request).strip()
  22. class EngineMixin:
  23. def get_template(self, template_name):
  24. return self.engine.get_template(template_name)
  25. @cached_property
  26. def engine(self):
  27. return self.backend(
  28. {
  29. "APP_DIRS": True,
  30. "DIRS": [Path(__file__).parent / self.backend.app_dirname],
  31. "NAME": "djangoforms",
  32. "OPTIONS": {},
  33. }
  34. )
  35. class DjangoTemplates(EngineMixin, BaseRenderer):
  36. """
  37. Load Django templates from the built-in widget templates in
  38. django/forms/templates and from apps' 'templates' directory.
  39. """
  40. backend = DjangoTemplates
  41. class Jinja2(EngineMixin, BaseRenderer):
  42. """
  43. Load Jinja2 templates from the built-in widget templates in
  44. django/forms/jinja2 and from apps' 'jinja2' directory.
  45. """
  46. @cached_property
  47. def backend(self):
  48. from django.template.backends.jinja2 import Jinja2
  49. return Jinja2
  50. class TemplatesSetting(BaseRenderer):
  51. """
  52. Load templates using template.loader.get_template() which is configured
  53. based on settings.TEMPLATES.
  54. """
  55. def get_template(self, template_name):
  56. return get_template(template_name)