Desactivar el almacenamiento en caché de archivos estáticos en el servidor de desarrollo Django

¿Hay una manera fácil de desactivar el almacenamiento en caché de archivos estáticos en el servidor de desarrollo de Django?

Estoy iniciando el servidor con el comando estándar:

$ python manage.py runserver 

Tengo settings.py configurado para servir archivos estáticos desde el directorio /static de mi proyecto Django. También tengo una clase de middleware que establece el encabezado de Cache-Control en must-revalidate, no-cache para el desarrollo, pero eso solo parece afectar a las URL que no están en mi directorio /static .

Suponiendo que está utilizando django.views.static.serve , no lo parece, pero escribir su propia vista que solo llame a django.views.static.serve , agregar el encabezado Cache-Control debería ser bastante fácil.

La respuesta de @Erik Forsberg funcionó para mí. Esto es lo que tenía que hacer:

  • Comente la aplicación staticfiles desde INSTALLED_APPS en settings.py :

     INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', #'django.contrib.staticfiles', ) 
  • Deje mi variable STATIC_URL establecida en settings.py :

     STATIC_URL = '/static/' 
  • Añadir una entrada a la base urls.py mi proyecto:

     # static files w/ no-cache headers url(r'^static/(?P.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}), 

Tenga en cuenta que también estoy configurando los encabezados de Cache-Control en una clase de middleware 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 

Y luego incluir eso en 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', ) 

La aplicación contrib.staticfiles de Django sirve automáticamente los archivos estáticos al anular el comando runserver . Con esta configuración no puede controlar la forma en que sirve los archivos estáticos.

Puede evitar que la aplicación staticfiles sirva los archivos estáticos agregando la opción –nostatic al comando runserver:

 ./manage.py runserver --nostatic 

Luego, puede escribir una configuración de url para servir manualmente los archivos estáticos con encabezados que impiden que el navegador almacene en caché la respuesta:

 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.*)$', never_cache(serve_static)), ) 

Si desea que su comando manage.py runserver tenga --nostatic opción --nostatic , puede poner esto en su manage.py :

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

Mi solución muy simple:

 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) 

En las versiones más recientes de Django, una solución muy simple es modificar las direcciones URL del proyecto así:

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

Llegué a esto observando cómo staticfiles modifica las direcciones URL automáticamente y simplemente agregando un decorador de vistas. Realmente no entiendo por qué esto no es el valor predeterminado, ya que es SOLO para el desarrollo. La vista puede manejar adecuadamente un encabezado HTTP “If-Modified-Since”, por lo que siempre se realiza una solicitud, pero el contenido solo se transfiere a los cambios (juzgados al observar la marca de tiempo de modificación en el archivo).

Para que esto funcione, debe agregar --nostatic al usar el runserver , de lo contrario, los cambios anteriores simplemente se ignorarán.

EDITACIÓN IMPORTANTE: Lo que tenía antes no funcionaba porque no estaba usando --nostatic y el decorador never_cache también incluía no-store que significaba que los archivos sin cambios siempre se re-transferían en lugar de devolver 304 Not Modified

Para Django más reciente, la forma en que se escriben las clases de middleware ha cambiado un poco.

Siga todas las instrucciones de @aaronstacy anteriores, pero para la clase de middleware, use esto:

 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 

Utilice whitenoise . Hay muchos problemas con el servicio de archivos estáticos en el servidor de ejecución y ya están todos corregidos en whitenoise . También es mucho más rápido. Han hablado de simplemente reemplazar el servicio estático incorporado con él , pero nadie lo ha logrado todavía.

Pasos para usarlo en desarrollo …

Instalar con pip install whitenoise

Agregue lo siguiente al final de settings.py:

 if DEBUG: MIDDLEWARE = ( 'whitenoise.middleware.WhiteNoiseMiddleware', ) + MIDDLEWARE INSTALLED_APPS = ( 'whitenoise.runserver_nostatic', ) + INSTALLED_APPS 

Esto no tiene nada con Django, porque nada cambió después de que reinstalé Django usando pip.

Este es el comportamiento del navegador, por lo que solo necesita borrar los archivos de imágenes en caché de su navegador.

Árbitro

Chrome Borrar caché y cookies

Es tan simple si estás usando Django 2.0+

Paso 1: haz ‘django.contrib.staticfiles’ como comentario en settings.py (nivel de proyecto)

INSTALLED_APPS = [

 # 'django.contrib.staticfiles', 

]

Paso 2: Importar seguimientos en urls.py (nivel de proyecto)

  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 

Paso 3: agregue la siguiente línea en urls.py (nivel de proyecto) después de los patrones de url

 urlpatterns = [ ] if settings.DEBUG: urlpatterns += static(settings.STATIC_URL, view=never_cache(serve)) 

Asegúrese de que STATIC_URL esté declarado en su configuración.py

 STATIC_URL = '/static/'