簡體   English   中英

關閉 Django 開發服務器中 static 文件的緩存

[英]Turn off caching of static files in Django development server

有沒有一種簡單的方法可以在 Django 的開發服務器中關閉 static 文件的緩存?

我正在使用標准命令啟動服務器:

$ python manage.py runserver

我已將settings.py配置為從我的 Django 項目的/static目錄中提供 static 文件。 我還有一個中間件 class 將Cache-Control header 設置為must-revalidate, no-cache用於開發,但這似乎只影響不在我的/static目錄中的 URL。

@Erik Forsberg 的回答對我有用。 這是我必須做的:

  • settings.py中從INSTALLED_APPS中注釋掉 staticfiles 應用程序:

     INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', #'django.contrib.staticfiles', )
  • settings.py中設置我的STATIC_URL變量:

     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}),

請注意,我還在中間件 class nocache.py中設置了Cache-Control標頭:

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 的contrib.staticfiles應用程序通過覆蓋runserver命令自動為您提供靜態文件。 使用此配置,您無法控制它為 static 文件提供服務的方式。

您可以通過在 runserver 命令中添加--nostatic選項來阻止 staticfiles 應用程序提供 static 文件:

./manage.py runserver --nostatic

然后,您可以編寫 url 配置來手動提供 static 文件,其標題會阻止瀏覽器緩存響應:

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')

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.

我非常簡單的解決方案:

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)

使用whitenoise 在 runserver 中提供的 static 文件存在很多問題,並且它們都已在whitenoise中修復。 它也更快。

他們已經討論過只是更換內置的 static 服務,但還沒有人解決這個問題。

在開發中使用它的步驟...

安裝pip install whitenoise

將以下內容添加到 settings.py 的末尾:

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

在較新版本的 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 header 因此始終發出請求,但僅在更改時傳輸內容(通過查看文件上的修改時間戳來判斷)。

為此,您必須在使用runserver時添加--nostatic ,否則上述更改將被忽略。

重要編輯:我以前沒有工作,因為我沒有使用--nostatic並且never_cache裝飾器還包括no-store這意味着始終重新傳輸未更改的文件而不是返回304 Not Modified

對於較新的 Django,中間件類的編寫方式發生了一些變化。

按照上面@aaronstacy 的所有說明進行操作,但對於中間件 class,請使用以下命令:

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

如果您使用的是 Django 2.0+,那就太簡單了

第 1 步:在 settings.py(項目級別)中將 'django.contrib.staticfiles' 作為注釋

安裝應用程序 = [

# '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(project level) 中的 urlpatterns 之后添加以下行

urlpatterns = [

]

if settings.DEBUG:

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

確保在 settings.py 中聲明了 STATIC_URL

STATIC_URL = '/static/'

staticfiles 應用程序通過覆蓋 runserver 命令來實現 static 文件的服務。 我們也可以這樣做:再次覆蓋此命令並實現一個自定義處理程序來關閉緩存。

請注意,您的 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

這與 Django 無關,因為在我使用 pip 重新安裝 Django 后沒有任何變化。

這是瀏覽器的行為,因此您只需清除瀏覽器的緩存圖像文件即可。

參考

Chrome 清除緩存和 cookies

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM