Django не обновляет статические файлы
Это раздражает. У меня есть файл javascript, на который ссылается шаблон django:
<script src="{% static 'js/login.js' %} "></script>
Я внес некоторые изменения в этот файл js. Затем я обновляю страницу, и я не вижу изменений.
Если я удалю javascript из файла и поместил его в HTML, он будет работать корректно, но если я попытаюсь сделать это с помощью внешнего js файла, это не так. Я попытался закрыть сервер и запустить runerver несколько раз, я также попытался перейти с Firefox на Chrome. Это не имеет никакого смысла. Пожалуйста, помогите мне понять, я могу уйти с включением всех js внутри HTML, но это беспокоит меня, что я больше не могу делать это обычным способом.
Подробнее об этой ошибке (# $&% # weirdest вещь, которую я нашел):
javascript выглядит примерно так:
old_sentence = "Dig that hole, forget the sun" // this is what I want to change
$("#jqselector").text(old_sentence)
new_sentence = "Run, rabbit, run" // this is the new sentence, it just won't show up.
Итак, я изменил js и перезапустил сервер, но html показывает старое предложение. Затем я удалил ссылку на файл login.js и поместил все js внутри тегов script в HTML, конечно же, появится новое предложение. Затем я включаю файл login.js, комментирую js внутри html, но я удаляю все содержимое внутри файла login.js, делая его пустым файлом... но старое предложение все же появляется. Поэтому старый файл login.js должен быть обналичен где-то, я не знаю. Затем я открываю Chrome и снова пытаюсь использовать его, такую же проблему.
Что это может быть? есть ли опция заставить django обновлять статические файлы? Я думал, что перезапустить сервер было достаточно... я должен перезагрузить компьютер?:/lol.
Ответы
Ответ 1
-
Удаление статического файла python manage.py collectstatic --noinput --clear
. Это заранее очистит статику.
-
Очистить кеш браузера
-
Добавьте случайную строку после включения js файла, например jquery.js? rand = 23423423, с каждой загрузкой.
Помогло ли это?
Ответ 2
Похоже, что оба браузера имеют кешированный файл javascript. В Chrome вы можете очистить кеш, нажав Ctrl
+ Shift
+ Del
и пометив только "Кэшированные изображения и файлы". Возможно, Firefox имеет аналогичный ярлык.
Вы можете взглянуть на этот вопрос на советы по отключению кэширования статических файлов на вашем сервере разработки вообще.
Ответ 3
Вам нужно перебрать кеш браузера. Этот тег шаблона будет выводить основанный на времени uuid, когда DEBUG=True
. В противном случае он будет искать переменную среды PROJECT_VERSION
. Если это не найдено, он выведет статический номер версии.
import os
import uuid
from django import template
from django.conf import settings
register = template.Library()
@register.simple_tag(name='cache_bust')
def cache_bust():
if settings.DEBUG:
version = uuid.uuid1()
else:
version = os.environ.get('PROJECT_VERSION')
if version is None:
version = '1'
return '__v__={version}'.format(version=version)
Вы бы использовали в шаблоне, как это:
{% load cache_bust %}
<link rel="stylesheet" href="{% static "css/project.css" %}?{% cache_bust %}"/>
и вот результат:
<link rel="stylesheet" href="/static/css/project.css?__v__=7d88de4e-7258-11e7-95a7-0242ac130005"/>
Ответ 4
Я тоже много часов боролся с этой проблемой. Я попытался ввести случайную строку, используя Javascript, но этот метод кажется глупым и уродливым. Одним из возможных способов решения этой проблемы является введение пользовательского тега. Подробнее см. :
В частности, вам нужно создать пакет под названием templatetags
в любых приложениях, которые вы создали (или создать новый, если хотите). И вы создаете любой файл в этом пакете и пишете что-то вроде этого:
from django import template
from django.utils.crypto import get_random_string
from django.templatetags import static
register = template.Library()
class StaticExtraNode(static.StaticNode):
def render(self, context):
return super().render(context) + '?v=' + get_random_string(32)
@register.tag('static_no_cache')
def do_static_extra(parser, token):
return StaticExtraNode.handle_token(parser, token)
def static_extra(path):
return StaticExtraNode.handle_simple(path)
то вы можете использовать тег {% static_no_cache '.../.../path...' %}
для создания пути со случайными аргументами!
Надеюсь, это поможет!
Ответ 5
Вместо использования сложных решений вы можете добавить дополнительный параметр для ваших включений в шаблоны.
Для статических включает в себя:
<script src="{% static 'js/polls/polls.js' %}?version=1"></script>
Для прямого включает в себя:
<link rel="stylesheet" type="text/css" href="/site_media/css/style.css?version=1" />
Обратите внимание на ?version=1
в коде. Каждый раз, когда вы изменяете файл css/js, меняйте эту версию в шаблоне, чтобы браузер был вынужден перезагрузить файл.
И если вы хотите вообще избежать кеширования по неизвестной причине, вы можете использовать текущую метку времени вместо версии:
<link rel="stylesheet" type="text/css" href="/site_media/css/style.css?{% now "U" %}" />
Ответ 6
Чтобы обновить статические файлы, вы должны снова запустить python manage.py collectstatic
.
Ответ 7
Если ничего не работает, найдите имя файла в проекте и найдите неожиданную копию. Если вы в какой-то момент сохранили неправильное местоположение (другое приложение) или раскололи новое приложение со старого, приоритет загрузки может играть трюки.
Ответ 8
Если вы не хотите обновлять кэш браузера каждый раз, когда вы меняете свои файлы CSS и JavaScript, или во время стилизации изображений, вам нужно динамически установить STATIC_URL
с изменяющимся компонентом пути. При динамически изменяющемся URL-адресе каждый раз, когда код обновляется, браузер посетителя будет принудительно загружать все новые некэшированные статические файлы. В этом рецепте мы установим динамический путь для STATIC_URL
используя время последнего редактирования в ОС.
import os
from datetime import datetime
def get_file_changeset(absolute_path):
timestamp = max(map(lambda x: os.path.getmtime(x[0]), os.walk(os.path.join(absolute_path, 'static'))))
try:
timestamp = datetime.utcfromtimestamp(int(timestamp))
except ValueError:
return ""
changeset = timestamp.strftime('%Y%m%d%H%M%S')
return changeset
И следующее изменение в ваших SETTINGS
:
from utils.misc import get_file_changeset
STATIC_URL = "/static/%s/" % get_file_changeset(BASE_DIR)
Как это устроено:
Функция get_file_changeset()
принимает каталог absolute_path
в качестве параметра и вызывает os.path.getmtime()
для каждого файла в каждом вложенном каталоге и находит последний отредактированный файл (с его максимальным временем редактирования). Временная метка анализируется; преобразуется в строку, состоящую из года, месяца, дня, часа, минут и секунд; вернулся; и включен в определение STATIC_URL
.
Примечание. При этом вам придется перезагружать dev-сервер каждый раз, когда вы редактируете статические файлы.
Ответ 9
Одним из решений является изменение настроек на следующее:
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
Для этого создается копия статического файла с хэшем содержимого в имени файла (при запуске collectstatic
). Таким образом, при изменении содержимого имя файла изменяется и старый кэш не будет использоваться. Единственная проблема в этом состоит в том, что он не используется в режиме DEBUG = True
поэтому для полной перезагрузки необходимо выполнить перезагрузку.
Вы можете прочитать документы на ManifestStaticFilesStorage для получения дополнительной информации.
РЕДАКТИРОВАТЬ: Я нашел решение, чтобы убедиться, что статические файлы не кэшируются в Dev и разместил его на другой вопрос.
Ответ 10
Для меня после повторного сбора статических файлов Just Changes отражены для меня.
$ python manage.py collectstatic --noinput --clear
Теперь запустите свой сервер, надеюсь, он работает.
$ python manage.py runserver
Ответ 11
Ваш браузер будет кэшировать изображения и файлы (включая javascript). Во-первых, очистите только ваши кешированные изображения и файлы. Затем используйте режим инкогнито в хромированном или приватном браузере в firefox, в то время как вы вносите изменения в свои .js файлы, чтобы сразу их увидеть после обновления страницы.