Проблемы с обновлением кэша шаблонов Django

#django #templates #caching #browser #refresh

#django #шаблоны #кэширование #браузер #обновить

Вопрос:

Я пытался написать простое приложение на Django для кэширования некоторых внешних изображений и отображения / обновления их по запросу.

Что я делаю, так это:

{% load cache %}
{% cache 1500 image %}

{% endcache %}


и обновление выполняет это в коде просмотра при нажатии на «кнопку» обновления:

key = "template.cache.image.d41d8cd98f00b204e9800998ecf8427e"
cache.delete( key )

Теперь все работает нормально, когда изображение удаляется или я заменяю src на какое-то другое значение. Это также работает, когда я набираю что-то внутри {% cache ... %} {% endcache %} тегов, но когда изображение меняется — например, я заменяю его каким-то другим — кнопка обновления ничего с ним не делает, пока я не обновлю всю страницу кнопкой обновления браузера (или с помощью F5). Я тестировал это в Chrome (некоторые версии) и Opera (11). В моем представлении не используются какие-либо параметры кэша, но я попробовал это с @never_cache и некоторыми другими тегами, и ничего не помогло.

Я надеюсь, вы сможете мне с этим помочь.

С наилучшими пожеланиями.

Редактировать: Что я точно пытаюсь сделать, так это кэшировать изображение и обновлять его по запросу. Возможно, требуется некоторая работа на python для получения изображения, кэширования хэша ответа, а затем повторного кэширования изображения (путем его удаления, если его предыдущий хэш изменился), но я понятия не имею, как «отправить» изображение через python HttpResponse / render_to_response в «html form» для его отображения.

Комментарии:

1. Когда вы говорите, что понятия не имеете, как отправить изображение через python, пытаетесь ли вы отправить URL-адрес или двоичный объект, который вы хотите затем отобразить на странице? Увидев пример кода с тем, что у вас есть сейчас, было бы намного проще помочь вам.

Ответ №1:

Ответ Кена работает для меня.

Если вы используете django, в шаблоне просто используйте что-то вроде

     <img src="/image.jpg?cachebuster={{uuid}}" /> 
  

и передайте uuid со стороны сервера.

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

Ответ №2:

Вы сохраняете то же имя изображения, но меняете изображение? Я предполагаю, что это кэш браузера, который вызывает у вас проблемы, а не кэш django.

Попробуйте добавить строку запроса в конец изображения, это должно помочь аннулировать кэш браузера. не имеет значения, что вы вводите в строку запроса, это просто должно быть уникальным

<img src="/image.jpg?cachebuster=blah23" />

Комментарии:

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

2. @user767849 Я не уверен, почему это не будет работать для внешних ресурсов? Можете ли вы опубликовать код, который вы используете для отображения изображений? У вас есть фрагменты выше, но было бы неплохо просмотреть весь код шаблона.

Ответ №3:

У меня возникла проблема с обновлением кэша браузера, и ответ Кена Кокрейна привел меня к решению.

Моя проблема была со страницей сведений о модели. После обновления записи, вернувшись на страницу сведений, браузер показал, что было в кэше — страница без обновлений. Это был большой отстой! Представьте себе замешательство пользователя после сохранения некоторых обновлений, только для того, чтобы неправильно понять на странице сведений (версия кэша браузера), что обновления не были сохранены! Но они были сохранены, проблема заключалась в том, что браузер показывал кэшированную версию.

Решение Кена Кокрейна: добавление строки запроса с чем-то уникальным. У меня это сработало! Сначала я просто добавил timezone.now(), отформатированный для совместимости с URL, например ?utc=2018-02-19_22.57.30 (в URL двоеточия указывают порт, двоеточия запутывают URL-адрес — двоеточия использовать нельзя).

Строка формата python: ‘%Y-%m-%d_%H.%M.%S’

Это решило мою проблему, но это заставляло обновлять каждый раз, когда пользователь возвращался на страницу подробного просмотра, даже когда обновления не было. Затем мне пришло в голову: вместо использования timezone.now() используйте временную метку последнего обновления строки модели. После обновления отметка времени последнего обновления будет более поздней, чем предыдущая, поэтому браузер обновится. Если пользователь вернется снова без какого-либо обновления, временная метка последнего обновления будет такой же, поэтому браузер сможет отобразить кэшированную страницу.

Итак, моя строка запроса?обновлено=2018-02-19_22.57.30

Решение может быть использовано при сохранении того же имени изображения, но изменении файла изображения, используя временную метку файловой системы файла изображения для строки запроса. Только при изменении изображения временная метка будет другой, и браузер обновится. Когда файл изображения остается тем же, временная метка будет такой же, поэтому браузер может отображать кэшированную версию.