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

aar*_*acy 29 python django

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

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

$ python manage.py runserver
Run Code Online (Sandbox Code Playgroud)

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

aar*_*acy 19

@Erik Forsberg的回答对我有用.这就是我必须做的事情:

  • 从应用注释掉staticfiles INSTALLED_APPSsettings.py:

    INSTALLED_APPS = (
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.sites',
        'django.contrib.messages',
        #'django.contrib.staticfiles',
    )
    
    Run Code Online (Sandbox Code Playgroud)
  • 将我的STATIC_URL变量设置为settings.py:

    STATIC_URL = '/static/'
    
    Run Code Online (Sandbox Code Playgroud)
  • 在项目的基础上添加一个条目urls.py:

    # static files w/ no-cache headers
    url(r'^static/(?P<path>.*)$', 'django.views.static.serve',
        {'document_root': settings.STATIC_ROOT}),
    
    Run Code Online (Sandbox Code Playgroud)

请注意,我还在Cache-Control中间件类中设置标头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
Run Code Online (Sandbox Code Playgroud)

然后将其包含在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',
    )
Run Code Online (Sandbox Code Playgroud)

  • 对于应该开箱即用的东西来说相当复杂 (3认同)

git*_*rik 16

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

您可以通过向--nostaticrunserver命令添加选项来阻止staticfiles应用程序提供静态文件:

./manage.py runserver --nostatic
Run Code Online (Sandbox Code Playgroud)

然后你可以编写一个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>.*)$', never_cache(serve_static)),
    )
Run Code Online (Sandbox Code Playgroud)

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

if '--nostatic' not in sys.argv:
    sys.argv.append('--nostatic')
Run Code Online (Sandbox Code Playgroud)

  • 这是最简单的修复方法. (2认同)
  • 似乎有点奇怪,这是必要的;在开发期间(您应该根据建议使用 runserver 的唯一时间),您真的不希望缓存东西吗?在我看来,开发过程中的默认行为应该是 never_cache,并创建一个可选参数来打开 runserver 的缓存。意识到这不是 Django 建议的地方,但在研究这个主题时让我震惊。 (2认同)
  • @rednaw`-nostatic`不起作用. (2认同)

Eri*_*erg 9

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


Vla*_*lav 9

我的简单解决方案:

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)
Run Code Online (Sandbox Code Playgroud)

  • 嗯.这对我不起作用.我得到这个错误:`TypeError:serve()至少需要2个参数(给定1个)`.也许你打算用'django.conf.urls.static`代替?喜欢:`urlpatterns = static(settings.STATIC_URL,view = never_cache(serve))+ urlpatterns` (4认同)

Tim*_*all 8

使用whitenoise. runserver 中提供的静态文件存在很多问题,它们都已在whitenoise. 它也更快。

他们已经讨论过用 it 替换内置的静态服务,但还没有人了解它。

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

安装 pip install whitenoise

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

if DEBUG:
    MIDDLEWARE = [
        'whitenoise.middleware.WhiteNoiseMiddleware',
    ] + MIDDLEWARE
    INSTALLED_APPS = [
        'whitenoise.runserver_nostatic',
    ] + INSTALLED_APPS
Run Code Online (Sandbox Code Playgroud)


Tim*_*all 7

在较新版本的 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))
Run Code Online (Sandbox Code Playgroud)

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

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

重要编辑:我之前的东西不起作用,因为我没有使用--nostatic,而且never_cache装饰器也包括在内no-store,这意味着未更改的文件总是被重新传输而不是返回304 Not Modified