- 1. Вывод
В Django - Урок 035. Разные шаблоны для отрисовки разных типов контента в поисковой выдаче было показано, как отрисовывать разные шаблоны в зависимости от того, какой тип контента отрисовывается в результатах поиска на сайте. При этом ключевым моментом было то, что не нужно было делать условия проверки выбора шаблона. Информация о балбалоне хранилась в переменной TEMPLATE_PREVIEW, через которую шаблон был вставлен во включенный тег в шаблоне Django.
{% include object.TEMPLATE_PREVIEW %}
В этом способе есть один большой недостаток. Дело в том, что тег include при каждом своем вызове ищет шаблон. При большой нагрузке на сайт - это может значительно увеличить продолжительность ответа от сервера. Чтобы решить эту проблему, нужно как-то кэшировать паттерн. Поскольку для разных типов контента используются разные шаблоны, сделать это с помощью include_tag довольно проблематично.
Эта проблема была решена путем кэширования шаблона на уровне класса как переменной класса.
Этот механизм может быть реализован с помощью миксина.
class EInterfaceMixin: TEMPLATE_FULL = 'full.html' # путь к шаблону template_full = None # pattern caching variable # we will cache with the help of the class method, in which we pass the object for rendering, as well as the context of the request # request context is required to provide rendering functionality that is dependent on the current user @classmethod def __render_template_full(cls, obj, request_context): if not cls.template_full: cls.template_full = loader.get_template(cls.TEMPLATE_FULL) return cls.template_full.render({'object': obj, 'user': request_context['user']}) # method to render using context def render_template_full(self, request_context): return self.__render_template_full(self, request_context)
Далее необходимо зарегистрировать встроенный тег. Это нужно для того, чтобы при рендеринге в шаблоне подобрать контекст запроса. В моем случае часть шаблонов не может корректно отображаться без информации о текущем пользователе, который находится на сайте.
@register.simple_tag(takes_context=True) def render_template_full(context, obj): if obj: return obj.render_template_full(context) return ''
Use in template
{% load render_template_full from core %} {% for object in object_list %} {% render_template_full object %} {% empty %}
Вывод
Этот миксин можно добавить ко всем моделям, которые будут использовать этот движок рендеринга.
При первом вызове метода класса шаблон будет кэширован. При последующих вызовах рендеринга будет использоваться уже кэшированный шаблон. Таким образом, не будет бесполезной траты процессорного времени на поиск шаблона при каждом вызове тега include