关闭 Django 开发服务器中静态文件的缓存

发布于 2024-11-29 07:01:34 字数 383 浏览 3 评论 0 原文

有没有一种简单的方法可以关闭 Django 开发服务器中静态文件的缓存?

我使用标准命令启动服务器:

python manage.py runserver

我已经配置了 settings.py从我的 Django 项目的 /static 目录提供静态文件。我还有一个中间件类,它将 Cache-Control 标头设置为 must-revalidate, no-cache 进行开发,但这似乎只影响不在我的 /static 目录中。

Is there an easy way to turn off caching of static files in Django's development server?

I'm starting the server with the standard command:

python manage.py runserver

I've got settings.py configured to serve up static files from the /static directory of my Django project. I've also got a middleware class that sets the Cache-Control header to must-revalidate, no-cache for development, but that only seems to affect URLs that are not in my /static directory.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

笑饮青盏花 2024-12-06 07:01:34

@Erik Forsberg 的答案对我有用。这是我必须做的:

  • settings.py 中注释掉 INSTALLED_APPS 中的静态文件应用程序:

    <前><代码>已安装的应用程序 = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    #'django.contrib.staticfiles',

  • 将我的 STATIC_URL 变量设置保留在settings.py

    STATIC_URL = '/static/'
    
  • 向我的项目的基 urls.py 添加一个条目代码>:

    # 带有无缓存标头的静态文件
    url(r'^static/(?P.*)
    

请注意,我还在中间件类中设置 Cache-Control 标头 < code>nocache.py:

class NoCache(object):
    def process_response(self, request, response):
        """
        set the "Cache-Control" header to "must-revalidate, no-cache"
        """
        if request.path.startswith('/static/'):
            response['Cache-Control'] = 'must-revalidate, no-cache'
        return response

然后将其包含在 settings.py 中:

if DEBUG:
    MIDDLEWARE_CLASSES = (
        'django.middleware.common.CommonMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'nocache.NoCache',
    )
, 'django.views.static.serve', {'document_root': 设置.STATIC_ROOT}),

请注意,我还在中间件类中设置 Cache-Control 标头 < code>nocache.py:


然后将其包含在 settings.py 中:


@Erik Forsberg's answer worked for me. Here's what I had to do:

  • Comment out the staticfiles app from INSTALLED_APPS in settings.py:

    INSTALLED_APPS = (
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.sites',
        'django.contrib.messages',
        #'django.contrib.staticfiles',
    )
    
  • Leave my STATIC_URL variable set in settings.py:

    STATIC_URL = '/static/'
    
  • Add an entry to my project's base urls.py:

    # static files w/ no-cache headers
    url(r'^static/(?P<path>.*)
    

Note that I'm also setting the Cache-Control headers in a middleware class nocache.py:

class NoCache(object):
    def process_response(self, request, response):
        """
        set the "Cache-Control" header to "must-revalidate, no-cache"
        """
        if request.path.startswith('/static/'):
            response['Cache-Control'] = 'must-revalidate, no-cache'
        return response

And then including that in settings.py:

if DEBUG:
    MIDDLEWARE_CLASSES = (
        'django.middleware.common.CommonMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'nocache.NoCache',
    )
, 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),

Note that I'm also setting the Cache-Control headers in a middleware class nocache.py:


And then including that in settings.py:



    
电影里的梦 2024-12-06 07:01:34

Django 的 contrib.staticfiles 应用程序通过覆盖 runserver 命令自动为您提供静态文件。使用此配置,您无法控制它提供静态文件的方式。

您可以通过添加 --nostatic runserver 命令选项:

./manage.py runserver --nostatic

然后您可以编写一个 url 配置来手动提供带有阻止浏览器缓存响应的标头的静态文件:

from django.conf import settings
from django.contrib.staticfiles.views import serve as serve_static
from django.views.decorators.cache import never_cache

urlpatterns = patterns('', )

if settings.DEBUG:
    urlpatterns += patterns('',
        url(r'^static/(?P<path>.*)

如果您希望您的 manage.py runserver 命令默认启用 --nostatic 选项,您可以将其放入 manage.py 中:

if '--nostatic' not in sys.argv:
    sys.argv.append('--nostatic')
, never_cache(serve_static)), )

如果您希望您的 manage.py runserver 命令默认启用 --nostatic 选项,您可以将其放入 manage.py 中:


Django's contrib.staticfiles app automatically serves staticfiles for you by overriding the runserver command. With this configuration you can't control the way it serves the static files.

You can prevent the staticfiles app from serving the static files by adding the --nostatic option to the runserver command:

./manage.py runserver --nostatic

Then you can write an url config to manually serve the static files with headers that prevent the browser from caching the response:

from django.conf import settings
from django.contrib.staticfiles.views import serve as serve_static
from django.views.decorators.cache import never_cache

urlpatterns = patterns('', )

if settings.DEBUG:
    urlpatterns += patterns('',
        url(r'^static/(?P<path>.*)

If you want your manage.py runserver command to have the --nostatic option on by default, you can put this in your manage.py:

if '--nostatic' not in sys.argv:
    sys.argv.append('--nostatic')
, never_cache(serve_static)), )

If you want your manage.py runserver command to have the --nostatic option on by default, you can put this in your manage.py:



    
彩虹直至黑白 2024-12-06 07:01:34

假设您正在使用 django.views.static.serve ,它看起来不像 - 但编写您自己的视图,仅调用 django.views.static.serve ,添加 Cache-Control 标头应该相当容易。

Assuming you're using django.views.static.serve, it doesn't look like it - but writing your own view that just calls django.views.static.serve, adding the Cache-Control header should be rather easy.

无所谓啦 2024-12-06 07:01:34

使用白噪声。 runserver 中的静态文件存在很多问题,并且这些问题都已在 whitenoise 中得到修复。它也快得多。

他们讨论过用它替换内置静态服务,但是还没有人抽出时间来解决这个问题。

在开发中使用它的步骤...

使用 pip installwhitenoise 安装

将以下内容添加到 settings.py 的末尾:

if DEBUG:
    MIDDLEWARE = [
        'whitenoise.middleware.WhiteNoiseMiddleware',
    ] + MIDDLEWARE
    INSTALLED_APPS = [
        'whitenoise.runserver_nostatic',
    ] + INSTALLED_APPS

Use whitenoise. There's a lot of issues with the static file serving in runserver and they're all already fixed in whitenoise. It's also WAY faster.

They've talked about just replacing the built-in static serving with it, but no one has gotten around to it yet.

Steps to use it in development...

Install with pip install whitenoise

Add the following to the end of settings.py:

if DEBUG:
    MIDDLEWARE = [
        'whitenoise.middleware.WhiteNoiseMiddleware',
    ] + MIDDLEWARE
    INSTALLED_APPS = [
        'whitenoise.runserver_nostatic',
    ] + INSTALLED_APPS
属性 2024-12-06 07:01:34

我的解决方案非常简单:

from django.contrib.staticfiles.views import serve
from django.views.decorators.cache import never_cache

static_view = never_cache(serve)
urlpatterns += static_view(settings.MEDIA_URL,
                           document_root=settings.MEDIA_ROOT)

My very simple solution:

from django.contrib.staticfiles.views import serve
from django.views.decorators.cache import never_cache

static_view = never_cache(serve)
urlpatterns += static_view(settings.MEDIA_URL,
                           document_root=settings.MEDIA_ROOT)
掀纱窥君容 2024-12-06 07:01:34

在较新版本的 Django 中,一个非常简单的解决方案是修改项目 url,如下所示:

from django.conf.urls.static import static
from django.contrib.staticfiles.views import serve
from django.views.decorators.cache import cache_control
from django.conf import settings

# YOUR urlpatterns here... 

if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, view=cache_control(no_cache=True, must_revalidate=True)(serve))

我通过查看 staticfiles 如何自动修改 url 并仅添加视图装饰器来实现此目的。我真的不明白为什么这不是默认值,因为这仅用于开发。该视图能够正确处理“If-Modified-Since”HTTP 标头,因此始终会发出请求,但内容仅在更改时传输(通过查看文件上的修改时间戳来判断)。

为此,您在使用 runserver必须添加 --nostatic,否则上述更改将被忽略。

重要编辑:我之前所做的不起作用,因为我没有使用 --nostatic 并且 never_cache 装饰器还包含 no-store 这意味着未更改的文件始终会重新传输,而不是返回 304 Not Modified

In newer versions of Django a very simple solution is modify the project urls like so:

from django.conf.urls.static import static
from django.contrib.staticfiles.views import serve
from django.views.decorators.cache import cache_control
from django.conf import settings

# YOUR urlpatterns here... 

if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, view=cache_control(no_cache=True, must_revalidate=True)(serve))

I arrived at this by looking at how staticfiles modifies the urls automatically and just adding a view decorator. I really don't understand why this isn't the default as this is for development ONLY. The view is able to properly handle a "If-Modified-Since" HTTP header so a request is always made but contents are only transferred on changes (judged by looking at the modification timestamp on the file).

For this to work you must add --nostatic when using runserver, otherwise the above changes are simply ignored.

IMPORTANT EDIT: What I had before didn't work because I wasn't using --nostatic and the never_cache decorator also included no-store which meant unchanged files were always being re-transferred instead of returning 304 Not Modified

£噩梦荏苒 2024-12-06 07:01:34

对于较新的 Django,中间件类的编写方式发生了一些变化。

请遵循上面 @aaronstacy 的所有说明,但对于中间件类,请使用以下命令:

class NoCache(object):
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        response['Cache-Control'] = 'must-revalidate, no-cache'
        return response

For newer Django, the way middleware classes are written has changed a bit.

Follow all the instructions from @aaronstacy above, but for the middleware class, use this:

class NoCache(object):
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        response['Cache-Control'] = 'must-revalidate, no-cache'
        return response
不疑不惑不回忆 2024-12-06 07:01:34

如果您使用 Django 2.0+,那就很简单

步骤 1:在 settings.py 中将 'django.contrib.staticfiles' 作为注释(项目级别)

INSTALLED_APPS = [

# 'django.contrib.staticfiles',

]

步骤 2:在 urls.py 中导入以下内容(项目级别)

     from django.conf.urls.static import static

     from django.contrib.staticfiles.views import serve

     from django.views.decorators.cache import never_cache

     from . import settings

步骤 3:在 urls.py(项目级别)中的 urlpatterns 之后添加以下行

urlpatterns = [

]

if settings.DEBUG:

    urlpatterns += static(settings.STATIC_URL, view=never_cache(serve))

确保在 settings.py 中声明了 STATIC_URL

STATIC_URL = '/static/'

It's so simple if you are using Django 2.0+

Step-1 : Make 'django.contrib.staticfiles' as comment in settings.py(Project level)

INSTALLED_APPS = [

# 'django.contrib.staticfiles',

]

Step-2 : Import followings in urls.py (Project level)

     from django.conf.urls.static import static

     from django.contrib.staticfiles.views import serve

     from django.views.decorators.cache import never_cache

     from . import settings

Step-3 : Add following line in urls.py(project level) after urlpatterns

urlpatterns = [

]

if settings.DEBUG:

    urlpatterns += static(settings.STATIC_URL, view=never_cache(serve))

Make sure that STATIC_URL is declared in your settings.py

STATIC_URL = '/static/'
九局 2024-12-06 07:01:34

staticfiles 应用程序通过 覆盖 runserver 命令。我们可以做同样的事情:再次覆盖此命令并实现一个关闭缓存的自定义处理程序。

请注意,您的 django 应用程序必须位于 INSTALLED_APPS 中的 django.contrib.staticfiles 之前,否则您的命令将被忽略。

# your_django_app/management/commands/runserver.py

from django.utils.cache import add_never_cache_headers
from django.contrib.staticfiles.handlers import (
    StaticFilesHandler as BaseStaticFilesHandler,
)
from django.contrib.staticfiles.management.commands.runserver import (
    Command as RunserverCommand,
)


class StaticFilesHandler(BaseStaticFilesHandler):
    def serve(self, request):
        response = super().serve(request)
        add_never_cache_headers(response)
        return response


class Command(RunserverCommand):
    def get_handler(self, *args, **options):
        handler = super().get_handler(*args, **options)

        # Check that serving static files is enabled
        if isinstance(handler, BaseStaticFilesHandler):
            # If yes, replace the original handler with our custom handler
            handler = StaticFilesHandler(handler.application)

        return handler

The staticfiles app implements serving of static files by overriding the runserver command. We can do the same: override this command again and implement a custom handler which turns off caching.

Note that your django application must be before django.contrib.staticfiles in INSTALLED_APPS, otherwise your command will be ignored.

# your_django_app/management/commands/runserver.py

from django.utils.cache import add_never_cache_headers
from django.contrib.staticfiles.handlers import (
    StaticFilesHandler as BaseStaticFilesHandler,
)
from django.contrib.staticfiles.management.commands.runserver import (
    Command as RunserverCommand,
)


class StaticFilesHandler(BaseStaticFilesHandler):
    def serve(self, request):
        response = super().serve(request)
        add_never_cache_headers(response)
        return response


class Command(RunserverCommand):
    def get_handler(self, *args, **options):
        handler = super().get_handler(*args, **options)

        # Check that serving static files is enabled
        if isinstance(handler, BaseStaticFilesHandler):
            # If yes, replace the original handler with our custom handler
            handler = StaticFilesHandler(handler.application)

        return handler
旧街凉风 2024-12-06 07:01:34

使用 whitenoise,您可以禁用浏览器缓存 Django 的静态文件。

首先,安装 whitenoise ,如下所示:

pip install whitenoise

然后,您必须在 django.contrib.staticfiles 之前设置 whitenoise.runserver_nostatic “https://docs.djangoproject.com/en/4.2/ref/settings/#installed-apps” rel="nofollow noreferrer">INSTALLED_APPS 并设置WhiteNoiseMiddleware 就在 SecurityMiddleware 之后MIDDLEWARE in settings.py 如下所示,否则您的浏览器仍然会缓存 Django 中的静态文件:

# "settings.py"

INSTALLED_APPS = [
    ...
    'whitenoise.runserver_nostatic', # Here
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware', # Here
    ...
]

最后,我建议在设置 whitenoise 按照我的回答,因为你的浏览器仍然会保留 Django 静态文件的缓存。 *在 Google Chrome 上,您可以使用 Ctrl+Shift+Del 打开页面清除缓存,这也适用于 Firefox。或者您可以清空缓存并使用 Ctrl+F5Shift+F5Ctrl 重新加载页面+Shift+R (在 Firefox 中为 Ctrl+F5Ctrl+Shift+R)。或者,您可以使用 Google Chrome 扩展程序清除缓存来清除缓存

With whitenoise, you can disable your browser to cache the static files of Django.

So first, install whitenoise as shown below:

pip install whitenoise

Then, you must set whitenoise.runserver_nostatic just before django.contrib.staticfiles in INSTALLED_APPS and set WhiteNoiseMiddleware just after SecurityMiddleware in MIDDLEWARE in settings.py as shown below otherwise your browser still caches the static files in Django:

# "settings.py"

INSTALLED_APPS = [
    ...
    'whitenoise.runserver_nostatic', # Here
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware', # Here
    ...
]

Lastly, I recommend to clear browser's cache after setting whitenoise following my answer here because your browser will still keep the cache of the static files of Django. *On Google Chrome, you can open the page to clear cache with Ctrl+Shift+Del which also works on Firefox. Or you can empty cache and reload the page with Ctrl+F5, Shift+F5 or Ctrl+Shift+R (Ctrl+F5 or Ctrl+Shift+R in Firefox). Or you can use the Google Chrome extension Clear Cache to clear cache

_畞蕅 2024-12-06 07:01:34

使用 never_cache<来自 django.views.decorators.cache 的 /code> 装饰器来修补默认的 django.views.static.serve

例如,您可以在开发设置文件中使用它:

import django.views.static
from django.views.decorators.cache import never_cache

django.views.static.serve = never_cache(django.views.static.serve)

Use the never_cache decorator from django.views.decorators.cache to patch the default django.views.static.serve.

For example, you could use this in your development settings file:

import django.views.static
from django.views.decorators.cache import never_cache

django.views.static.serve = never_cache(django.views.static.serve)
不一样的天空 2024-12-06 07:01:34

这与 Django 无关,因为我使用 pip 重新安装 Django 后没有任何变化。

这是浏览器的行为,因此您只需清除浏览器的缓存图像文件即可。

参考

Chrome 清除缓存和 Cookie

This has nothing with Django, because nothing changed after I reinstall Django using pip.

This is the behavior of browser, so you just need to clear cached images files of your browser.

Ref

Chrome Clear cache and cookies

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文