【问题标题】:Django won't refresh staticfilesDjango不会刷新静态文件
【发布时间】: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 以避免提供旧内容stackoverflow.com/a/12632061/4061047
  • 我不确定这是否仍然相关,但如果您设置了 staticfiles_dirs 并且不仅是静态根目录,那么 django 可能会在开发环境中提供来自 _dirs 的静态文件,而不是来自根。这就是发生在我身上的事情。如果我在根目录中处理静态文件,则在运行 collectstatic 之前不会应用任何更改。如果我在 _dir 中处理静态文件,则 Ctrl+F5 会应用更改。

标签: django django-staticfiles


【解决方案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】:

      静态文件的更改不起作用”。这可能有多种原因。

      1. 您的浏览器是storing cache 的静态文件。

        解决方案(一):打开Incognito/Private window

        解决方案(2):使用硬刷新:

        • 对于 mac:cmd + shift + r
        • 对于其他人:ctr + shift + r
      2. 如果您在生产中遇到此问题,请按照以下步骤操作:

        • 通过以下命令删除 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 &amp;&amp; sudo systemctl reload nginx &amp;&amp; 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 不会改变任何内容。
                    猜你喜欢
                    • 2019-04-27
                    • 2021-08-25
                    • 2020-12-11
                    • 2018-10-09
                    • 2012-04-30
                    • 2017-10-08
                    • 2014-11-24
                    • 1970-01-01
                    • 2019-02-23
                    相关资源
                    最近更新 更多