Django不会刷新静态文件
Posted
技术标签:
【中文标题】Django不会刷新静态文件【英文标题】:Django won't refresh staticfiles 【发布时间】:2015-03-10 18:07:45 【问题描述】:我在 django 模板上引用了一个 javascript 文件:
<script src="% static 'js/login.js' % "></script>
我对该 js 文件进行了一些更改。然后,我刷新页面,我看不到更改发生。
如果我从文件中删除 JavaScript 并将其放入 html 中,它可以正常工作,但如果我尝试使用外部 js 文件执行此操作,则它不会。我已经尝试关闭服务器并运行 runserver 几次,我也尝试从 Firefox 更改为 Chrome。这根本没有意义。请帮助我理解,我可以将所有 js 包含在 HTML 中,但让我感到困扰的是,我不能再以正常的方式做到这一点了。
有关此错误的更多详细信息(我发现的 #$&%# 最奇怪的事情):
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
文件,注释掉html里面的js但是我删除了login.js
文件里面的所有内容,使它成为一个空文件……但是旧的句子仍然出现。
因此,旧的login.js
文件必须在我不知道的某个地方兑现。然后我打开 Chrome 并再次尝试,同样的问题。
可能是什么?是否有强制 django 刷新静态文件的选项?我认为重新启动服务器就足够了。我应该重新启动计算机吗?
【问题讨论】:
你试过运行python manage.py collectstatic
吗?听起来您正在修改 javascript 的工作副本,并且它正在引用收集/过期的文件。
您是否尝试使用 Ctrl-F5 刷新页面并清除缓存?
感谢您的 cmets 和您的时间。我已经发现了错误,这确实是一个奇怪的错误。我发现 django 将本地环境静态文件指向我在部署时使用的 AWS 存储桶。所以...运行 collectstatic 是我猜的解决方案的一部分,剩下的就是重新配置我的静态文件设置并以某种方式解决 AWS Bucket 问题。
如果你在 django 中使用 uwsgi,你可能需要重启 uwsgi 以避免提供旧内容***.com/a/12632061/4061047
我不确定这是否仍然相关,但如果您设置了 staticfiles_dirs 并且不仅是静态根目录,那么 django 可能会在开发环境中提供来自 _dirs 的静态文件,而不是来自根。这就是发生在我身上的事情。如果我在根目录中处理静态文件,则在运行 collectstatic 之前不会应用任何更改。如果我在 _dir 中处理静态文件,则 Ctrl+F5 会应用更改。
【参考方案1】:
清除静态文件python manage.py collectstatic --noinput --clear
。这将事先清除静态。
清除浏览器缓存
在每次加载时在 js 文件包含后添加一个随机字符串,例如 jquery.js?rand=23423423
。
【讨论】:
第一个选项不适用于开发环境。最后一点是一个很好的提示,直到现在我一直在更改实际的文件名,但这要好得多:) 如何将随机参数添加到 ? 为什么要清除所有静态文件?这是否意味着您必须重新上传它们? 这毁了我的服务器!它删除了我的整个 git 存储库。为什么这是选定的答案? 我尝试了你的第一种方法,它删除了我所有的静态文件-.-【参考方案2】:对于窗口用户, ctrl+f5 在开发服务器上完成这项工作,如果这不起作用,则使用命令 python manage.py collectstatic 正在工作,否则某些答案中提到的其他方式确实有风险,所以最好备份您的静态文件。
【讨论】:
【参考方案3】:我今晚正在追逐一个 css 静态文件更改。通过 Django 教程。 我的 Django html 页面不会在我的 base.css 文件中显示更新后的 css。
我会看到原始的 base.css,但没有我对文件的更新。这是在开发环境中。
我不认为 django 仅在生产中运行 coll ecstatic 后才在 dev 上缓存静态。
为了快速解决问题,我更改了测试站点的名称。 base.css 文件到 base1.css 和 html 页面链接到 base1.css
重新加载的页面和我更新的 CSS 生效。没有最好的解决方案。但快速修复。
【讨论】:
【参考方案4】:“静态文件的更改不起作用”。这可能有多种原因。
您的浏览器是storing cache
的静态文件。
解决方案(一):打开Incognito/Private window
解决方案(2):使用硬刷新:
对于 mac:cmd + shift + r
对于其他人:ctr + shift + r
如果您在生产中遇到此问题,请按照以下步骤操作:
通过以下命令删除 staticfiles
文件夹:
sudo rm -rf staticfiles
[在你的项目目录中]
现在运行collectstatic
命令:python3 manage.py collectstatic
重启gunicorn
,通过以下命令:sudo systemctl restart gunicorn
重启nginx
,通过以下命令:sudo systemctl restart nginx
有时浏览器会将这些静态文件数据(作为缓存)存储一段时间。几个小时后问题可能会消失。
希望这能解决您的问题。
【讨论】:
不知道硬刷新功能。非常感谢。 第一点足以解决我的问题。谢谢。【参考方案5】:只需运行python manage.py collectstatic
就可以解决问题。然后使用ctrl + F5
硬刷新浏览器,这应该适用于所有浏览器。
【讨论】:
【参考方案6】:简单的摆脱方法,硬刷新cmd+shift+r/ctr+shift+r
硬刷新是一种清除特定页面的浏览器缓存的方法,以强制它加载页面的最新版本。
在浏览器上cmd+shift+r/ctr+shift+r
【讨论】:
请在您的答案中添加一些解释,以便其他人可以从中学习 - 是什么让您认为这比其他获得数十人支持的方法更有效? 而不是停止服务器并做一些额外的事情。即运行命令或向项目添加一些代码。只需通过 cmd+shift+r 刷新页面即可。 (硬刷新)硬刷新是一种清除特定页面的浏览器缓存的方法,强制它加载页面的最新版本。 请通过编辑将所有信息添加到您的答案中【参考方案7】:在重新收集静态文件后对我来说,Just Changes 反映在我身上。
$ python manage.py collectstatic --noinput --clear
现在运行你的服务器,希望它能正常工作。
$ python manage.py runserver
【讨论】:
【参考方案8】:您需要破坏浏览器缓存。当DEBUG=True
时,此模板标签将输出基于时间的 uuid。否则它将寻找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"/>
【讨论】:
这看起来是个不错的解决方案!但是究竟应该在哪里添加这段代码呢? @LuizTauffer 看看这个:docs.djangoproject.com/en/3.2/howto/custom-template-tags app 目录中应该有一个名为 templatetags 的文件夹,里面有这个文件(任何你想要的名字)和一个 init.py。然后使用 % file_name % 将其加载到模板中【参考方案9】:一种解决方案是将设置更改为以下内容:
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
这样做是创建静态文件的副本,文件名中包含内容哈希(运行collectstatic
时)。这样,当内容更改时,文件名也会更改,并且不会使用旧缓存。唯一的问题是它在 DEBUG = True
模式下无法使用,因此您必须执行 shift-reload 才能进行硬重载。
您可以阅读docs on ManifestStaticFilesStorage 了解更多信息。
编辑:我找到了 solution for making sure static files are not cached in dev 并将其发布在另一个问题上。
【讨论】:
【参考方案10】:如果您不想在每次更改 CSS 和 JavaScript 文件时或在设置图像样式时刷新浏览器缓存,则需要使用可变路径组件动态设置 STATIC_URL
。使用动态变化的 URL,每当更新代码时,访问者的浏览器将强制加载全新的未缓存静态文件。在这个秘籍中,我们将使用 os 中的上次编辑时间为 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
的定义中。注意:这样,您每次编辑静态文件时都必须重新加载开发服务器。
【讨论】:
【参考方案11】:您可以在模板中的包含中添加额外的参数,而不是使用复杂的解决方案。
对于静态包括:
<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" %" />
【讨论】:
这很奏效。我通常会全部重启:sudo systemctl daemon-reload && sudo systemctl reload nginx && sudo systemctl restart gunicorn
。但是这次它在我的 CSS 上不起作用。将版本直接添加到样式表链接就可以了。谢谢。【参考方案12】:
您的浏览器将缓存图像和文件(包括 JavaScript)。首先,只清除缓存的图像和文件。然后在更改 .js 文件时在 chrome 中使用隐身模式或在 firefox 中使用隐私浏览,以便在页面刷新后立即看到它们
【讨论】:
【参考方案13】:我也为这个问题苦苦挣扎了好几个小时。我曾尝试使用 Javascript 注入随机字符串,但这种方法看起来既愚蠢又丑陋。处理此问题的一种可能方法是引入自定义标签。详情请见document:
具体来说,您需要在您创建的任何应用程序中创建一个名为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...' %
来创建带有随机参数的路径!
我希望这会有所帮助!
【讨论】:
【参考方案14】:如果没有其他方法,请在项目中搜索文件名并查找意外副本。如果您在某个时间点保存到了错误的位置(不同的应用),或者从旧应用中分离出新应用,则加载优先级可能会欺骗您。
【讨论】:
【参考方案15】:听起来您的两个浏览器都缓存了 javascript 文件。在 Chrome 中,您可以通过按 Ctrl
+ Shift
+ Del
并勾选“缓存的图像和文件”来清除缓存。 Firefox 可能有类似的快捷方式。
您可以查看this question,了解在开发服务器上完全禁用静态文件缓存的技巧。
【讨论】:
没办法,作为一个优秀的程序员你不希望客户端以这种方式刷新:(【参考方案16】:要刷新静态文件,您应该再次运行 python manage.py collectstatic
。
【讨论】:
他在使用runserver
的开发服务器上。静态文件直接从其原始位置加载,因此collectstatic
不会改变任何内容。以上是关于Django不会刷新静态文件的主要内容,如果未能解决你的问题,请参考以下文章
django -静态文件能加载进入,但是在页面上却显示不出来
我在 django 中的静态文件不会被重新加载,除非我每次重新启动电脑时都重命名它们