loader.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import warnings
  2. from django.utils.deprecation import RemovedInDjango110Warning
  3. from . import engines
  4. from .backends.django import DjangoTemplates
  5. from .engine import (
  6. _context_instance_undefined, _dictionary_undefined, _dirs_undefined,
  7. )
  8. from .exceptions import TemplateDoesNotExist
  9. from .loaders import base
  10. def get_template(template_name, dirs=_dirs_undefined, using=None):
  11. """
  12. Loads and returns a template for the given name.
  13. Raises TemplateDoesNotExist if no such template exists.
  14. """
  15. chain = []
  16. engines = _engine_list(using)
  17. for engine in engines:
  18. try:
  19. # This is required for deprecating the dirs argument. Simply
  20. # return engine.get_template(template_name) in Django 1.10.
  21. if isinstance(engine, DjangoTemplates):
  22. return engine.get_template(template_name, dirs)
  23. elif dirs is not _dirs_undefined:
  24. warnings.warn(
  25. "Skipping template backend %s because its get_template "
  26. "method doesn't support the dirs argument." % engine.name,
  27. stacklevel=2)
  28. else:
  29. return engine.get_template(template_name)
  30. except TemplateDoesNotExist as e:
  31. chain.append(e)
  32. raise TemplateDoesNotExist(template_name, chain=chain)
  33. def select_template(template_name_list, dirs=_dirs_undefined, using=None):
  34. """
  35. Loads and returns a template for one of the given names.
  36. Tries names in order and returns the first template found.
  37. Raises TemplateDoesNotExist if no such template exists.
  38. """
  39. chain = []
  40. engines = _engine_list(using)
  41. for template_name in template_name_list:
  42. for engine in engines:
  43. try:
  44. # This is required for deprecating the dirs argument. Simply
  45. # use engine.get_template(template_name) in Django 1.10.
  46. if isinstance(engine, DjangoTemplates):
  47. return engine.get_template(template_name, dirs)
  48. elif dirs is not _dirs_undefined:
  49. warnings.warn(
  50. "Skipping template backend %s because its get_template "
  51. "method doesn't support the dirs argument." % engine.name,
  52. stacklevel=2)
  53. else:
  54. return engine.get_template(template_name)
  55. except TemplateDoesNotExist as e:
  56. chain.append(e)
  57. if template_name_list:
  58. raise TemplateDoesNotExist(', '.join(template_name_list), chain=chain)
  59. else:
  60. raise TemplateDoesNotExist("No template names provided")
  61. def render_to_string(template_name, context=None,
  62. context_instance=_context_instance_undefined,
  63. dirs=_dirs_undefined,
  64. dictionary=_dictionary_undefined,
  65. request=None, using=None):
  66. """
  67. Loads a template and renders it with a context. Returns a string.
  68. template_name may be a string or a list of strings.
  69. """
  70. if (context_instance is _context_instance_undefined
  71. and dirs is _dirs_undefined
  72. and dictionary is _dictionary_undefined):
  73. # No deprecated arguments were passed - use the new code path
  74. if isinstance(template_name, (list, tuple)):
  75. template = select_template(template_name, using=using)
  76. else:
  77. template = get_template(template_name, using=using)
  78. return template.render(context, request)
  79. else:
  80. chain = []
  81. # Some deprecated arguments were passed - use the legacy code path
  82. for engine in _engine_list(using):
  83. try:
  84. # This is required for deprecating properly arguments specific
  85. # to Django templates. Remove Engine.render_to_string() at the
  86. # same time as this code path in Django 1.10.
  87. if isinstance(engine, DjangoTemplates):
  88. if request is not None:
  89. raise ValueError(
  90. "render_to_string doesn't support the request argument "
  91. "when some deprecated arguments are passed.")
  92. continue
  93. # Hack -- use the internal Engine instance of DjangoTemplates.
  94. return engine.engine.render_to_string(
  95. template_name, context, context_instance, dirs, dictionary)
  96. elif context_instance is not _context_instance_undefined:
  97. warnings.warn(
  98. "Skipping template backend %s because its render_to_string "
  99. "method doesn't support the context_instance argument." %
  100. engine.name, stacklevel=2)
  101. elif dirs is not _dirs_undefined:
  102. warnings.warn(
  103. "Skipping template backend %s because its render_to_string "
  104. "method doesn't support the dirs argument." % engine.name,
  105. stacklevel=2)
  106. elif dictionary is not _dictionary_undefined:
  107. warnings.warn(
  108. "Skipping template backend %s because its render_to_string "
  109. "method doesn't support the dictionary argument." %
  110. engine.name, stacklevel=2)
  111. except TemplateDoesNotExist as e:
  112. chain.append(e)
  113. continue
  114. if template_name:
  115. if isinstance(template_name, (list, tuple)):
  116. template_name = ', '.join(template_name)
  117. raise TemplateDoesNotExist(template_name, chain=chain)
  118. else:
  119. raise TemplateDoesNotExist("No template names provided")
  120. def _engine_list(using=None):
  121. return engines.all() if using is None else [engines[using]]
  122. class BaseLoader(base.Loader):
  123. _accepts_engine_in_init = False
  124. def __init__(self, *args, **kwargs):
  125. warnings.warn(
  126. "django.template.loader.BaseLoader was superseded by "
  127. "django.template.loaders.base.Loader.",
  128. RemovedInDjango110Warning, stacklevel=2)
  129. super(BaseLoader, self).__init__(*args, **kwargs)