Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Turn off caching of static files in Django development server

Tags:

python

django

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.

like image 443
aaronstacy Avatar asked Aug 10 '11 15:08

aaronstacy


People also ask

Does Django cache static files?

Django caches (or rather the browsers cache) the static files indefinitely during development. Now even after the files are changed, the browsers will serve the stale file from the cache.

Does Django automatically cache?

Local Memory Cache Unless we explicitly specify another caching method in our settings file, Django defaults to local memory caching. As its name implies, this method stores cached data in RAM on the machine where Django is running. Local memory caching is fast, responsive, and thread-safe.

How does Django manage static files?

Configuring static filesMake sure that django.contrib.staticfiles is included in your INSTALLED_APPS . In your templates, use the static template tag to build the URL for the given relative path using the configured STATICFILES_STORAGE . Store your static files in a folder called static in your app.

How do you set cache control for static content?

Here is what you need to remember while caching static resources on CDN or local cache server: Use Cache-control HTTP directive to control who can cache the response, under which conditions, and for how long. Configure your server or application to send validation token Etag. Do not cache HTML in the browser.


2 Answers

@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>.*)$', '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:

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',     ) 
like image 133
aaronstacy Avatar answered Sep 26 '22 02:09

aaronstacy


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>.*)$', 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:

if '--nostatic' not in sys.argv:     sys.argv.append('--nostatic') 
like image 33
gitaarik Avatar answered Sep 26 '22 02:09

gitaarik