Кэширование фрагментов шаблона не работает для некоторых пользовательских тегов

Я реализовал кэширование в своем приложении django и использовал кэширование для каждого представления через API-интерфейс кэширования и кэширование фрагментов шаблона. На некоторых моих страницах я использую пользовательский тег шаблона django, этот тег предоставляется сторонним разработчиком, он принимает некоторые аргументы в своих шаблонных тегах, а затем отправляет запрос на удаленный сервер, возвращает ответ через XML и затем отображает результат на моей странице. Отлично - я думал, что смогу легко кешировать это, используя кеширование фрагментов, поэтому

{% load cache %}
{% cache 500 request.user.username %}
{% load third party custom tags %}
{% expensive custom tag set that gets stuff from a third party server via xml %}
{{ some.stuff}}
{% endcache %}

Проблема не в том, что я делаю, запросы по-прежнему отправляются на этот удаленный сервер, кажется, Django не любит кешировать эти пользовательские теги шаблонов. Я знаю, что memcached работает отлично, для других представлений и шаблонов все работает просто отлично. Я делаю что-то, что несовместимо с кэшированием фрагмента? Есть ли способ обойти это?

4 ответа

Если фрагмент шаблона, который вы пытаетесь кэшировать, не может быть обработан, memcached не сможет сохранить его и вызовет исключение. Из того, что я могу извлечь, исключения, генерируемые при рендеринге шаблонов Django, подавляются. Поскольку ваш пользовательский тег выполняет HTTP-запросы, возможно, объекты сокетов (которые не могут быть обработаны) каким-то образом сохраняются во фрагменте шаблона.

Если это так, то единственный способ обойти это - изменить пользовательский тег, чтобы избавиться от любых оставшихся объектов сокетов.

Я не думаю, что это имеет какое-либо отношение к пользовательскому тегу.

В итоге мы переписали кеширующий тег Django, потому что нам нужно было больше контроля, чем было возможно с тем, который был предоставлен. Вы можете сделать его копию самостоятельно и вставить в него некоторые отладочные операторы печати. В частности, проверьте имя файла (при условии, что вы кэшируете файлы) и посмотрите, что генерируется. Может случиться так, что он меняется, когда не должен (по неизвестной причине), и это будет означать, что ему всегда нужно повторно визуализировать закрытый блок.

Посмотрите в django/templatetags/cache.py. Это всего лишь 63 строки кода.

Вы пытались использовать другое имя для фрагмента кэша? Может быть проблема с использованием request.user.username по нескольким причинам:

  • Если пользователь не вошел в систему, request.user.username может быть пустым, что приведет к неназванному фрагменту кэша

  • Если пользователь вошел в систему, это будет вызывать сторонний тег шаблона хотя бы один раз для каждого пользователя каждые 3 минуты

Возможно стоит попробовать переименовать имя фрагмента кеша для проверки:

{% cache 500 customxml %}

Я также попытался бы загрузить сторонний тег шаблона вне тега кеша следующим образом:

{% load cache third_party_custom_tags %}
{% cache 500 request.user.username %}
{% expensive custom tag set that gets stuff from a third party server via xml %}
{{ some.stuff}}
{% endcache %}

В чем я не уверен, так это в том, что фреймворк кэширует результаты тега шаблона. Если это не сработает, я бы посмотрел на то, что делает тег шаблона под капотом, и заново реализовал тег шаблона, используя низкоуровневый кеш Django.

Я думаю, что проблема заключается в пользовательском теге, как вы предложили.

Я не согласен с тем, что request.user.username является проблемой, так как документация по теме фактически приводит это в качестве примера, и я использовал его с внутренним кэшированием (например, числом постов) в тестировании, и он работал нормально.,

Кэш низкого уровня потенциально полезен, но я бы посмотрел на ваш пользовательский тег, чтобы увидеть, что не будет кэшироваться. Без кода трудно угадать, но я думаю, что будет возвращаться что-то вроде времени или какой-то другой переменной, которая заставляет его инициировать обновление (если XML извлекает какие-либо данные, которые изменяют, Django может вызвать обновление, в зависимости от на других настройках). У меня были смешанные результаты с кэшированием в Django, поэтому я хотел бы взглянуть на ваши XML-фиды, чтобы увидеть, не вызывает ли это что-либо, чтобы остановить кэширование.

Другие вопросы по тегам