在Django的开发服务器中是否有一种简单的方法可以关闭静态文件的缓存?
我正在使用标准命令启动服务器:
$ python manage.py runserver
我已将settings.py
配置为从我的Django项目的/static
目录中提供静态文件。我还有一个中间件类,它将Cache-Control
标头设置为must-revalidate, no-cache
以进行开发,但这似乎只影响不在我的/static
目录中的URL。
答案 0 :(得分:19)
在INSTALLED_APPS
中注释settings.py
中的staticfiles应用:
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
中添加一个条目:
# static files w/ no-cache headers
url(r'^static/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.STATIC_ROOT}),
请注意,我还在中间件类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
然后将其包含在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',
)
答案 1 :(得分:16)
Django的contrib.staticfiles
应用程序会通过覆盖runserver
命令自动为您提供静态文件。使用此配置,您无法控制它为静态文件提供服务的方式。
您可以通过向runserver命令添加--nostatic
选项来阻止staticfiles应用程序提供静态文件:
./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>.*)$', never_cache(serve_static)),
)
如果您希望manage.py runserver
命令默认启用--nostatic
选项,则可以将其放在manage.py
中:
if '--nostatic' not in sys.argv:
sys.argv.append('--nostatic')
答案 2 :(得分:9)
假设您正在使用django.views.static.serve
,它看起来不像 - 但编写自己的视图只调用django.views.static.serve
,添加Cache-Control标头应该相当容易。
答案 3 :(得分: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)
答案 4 :(得分:2)
在较新版本的Django中,一个非常简单的解决方案是像这样修改项目网址:
from django.conf.urls.static import static
from django.contrib.staticfiles.views import serve
from django.views.decorators.cache import cache_control
# 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标头,因此始终发出请求,但仅在更改时传送内容(通过查看文件上的修改时间戳来判断)。
为此,您必须在使用--nostatic
时添加runserver
,否则上述更改将被忽略。
重要编辑:我以前没有用过,因为我没有使用--nostatic
,并且never_cache
装饰器还包含no-store
,这意味着未更改文件总是被重新传输,而不是返回304 Not Modified
答案 5 :(得分:1)
对于较新的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
答案 6 :(得分:1)
使用whitenoise
。运行服务器中提供的静态文件存在很多问题,并且这些问题已在whitenoise
中修复。它也更快。他们已经talked about just replacing the built-in static serving with it,但是还没有人解决。
在开发中使用它的步骤...
安装pip install whitenoise
将以下内容添加到settings.py的末尾:
if DEBUG:
MIDDLEWARE = (
'whitenoise.middleware.WhiteNoiseMiddleware',
) + MIDDLEWARE
INSTALLED_APPS = (
'whitenoise.runserver_nostatic',
) + INSTALLED_APPS
答案 7 :(得分:0)
这与Django没有任何关系,因为在使用pip重新安装Django之后没有任何改变。
这是浏览器的行为,因此您只需要清除浏览器的缓存图像文件。
答案 8 :(得分:0)
这很简单,如果您使用的是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步:在urlpatterns之后的urls.py(项目级别)中添加以下行
urlpatterns = [
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, view=never_cache(serve))
确保在您的settings.py中声明了STATIC_URL
STATIC_URL = '/static/'
答案 9 :(得分:0)
staticfiles 应用程序通过 overriding the runserver command 实现静态文件的服务。我们可以做同样的事情:再次覆盖这个命令并实现一个关闭缓存的自定义处理程序。
请注意,您的 django 应用程序必须位于 django.contrib.staticfiles
中的 INSTALLED_APPS
之前,否则您的命令将被忽略。
# 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