15👍
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.
21👍
@Erik Forsberg’s answer worked for me. Here’s what I had to do:
-
Comment out the staticfiles app from
INSTALLED_APPS
insettings.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 insettings.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',
)
- [Django]-How can I get MINIO access and secret key?
- [Django]-Django Query __isnull=True or = None
- [Django]-Location of Django logs and errors
20👍
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')
- [Django]-What's the difference between select_related and prefetch_related in Django ORM?
- [Django]-How to make the foreign key field optional in Django model?
- [Django]-Convert an IP string to a number and vice versa
13👍
Use whitenoise
. There’s a lot of issues with the static file serving in runserver and they’re all already fixed in whitenoise
. It’s also WAY faster.
They’ve talked about just replacing the built-in static serving with it, but no one has gotten around to it yet.
Steps to use it in development…
Install with pip install whitenoise
Add the following to the end of settings.py:
if DEBUG:
MIDDLEWARE = [
'whitenoise.middleware.WhiteNoiseMiddleware',
] + MIDDLEWARE
INSTALLED_APPS = [
'whitenoise.runserver_nostatic',
] + INSTALLED_APPS
- [Django]-How Can I Disable Authentication in Django REST Framework
- [Django]-IOError: request data read error
- [Django]-Django UniqueConstraint
10👍
My very simple solution:
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)
- [Django]-OSError – Errno 13 Permission denied
- [Django]-Django filter on the basis of text length
- [Django]-Exclude a field from django rest framework serializer
9👍
In newer versions of Django a very simple solution is modify the project urls like so:
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))
I arrived at this by looking at how staticfiles modifies the urls automatically and just adding a view decorator. I really don’t understand why this isn’t the default as this is for development ONLY. The view is able to properly handle a “If-Modified-Since” HTTP header so a request is always made but contents are only transferred on changes (judged by looking at the modification timestamp on the file).
For this to work you must add --nostatic
when using runserver
, otherwise the above changes are simply ignored.
IMPORTANT EDIT: What I had before didn’t work because I wasn’t using --nostatic
and the never_cache
decorator also included no-store
which meant unchanged files were always being re-transferred instead of returning 304 Not Modified
- [Django]-GeoDjango GEOSException error
- [Django]-PyCharm Not Properly Recognizing Requirements – Python, Django
- [Django]-How to change ForeignKey display text in the Django Admin?
1👍
For newer Django, the way middleware classes are written has changed a bit.
Follow all the instructions from @aaronstacy above, but for the middleware class, use this:
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]-Split views.py in several files
- [Django]-Handling race condition in model.save()
- [Django]-How do I prevent fixtures from conflicting with django post_save signal code?
1👍
It’s so simple if you are using Django 2.0+
Step-1 : Make ‘django.contrib.staticfiles’ as comment in settings.py(Project level)
INSTALLED_APPS = [
# 'django.contrib.staticfiles',
]
Step-2 : Import followings in urls.py (Project level)
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
Step-3 : Add following line in urls.py(project level) after urlpatterns
urlpatterns = [
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, view=never_cache(serve))
Make sure that STATIC_URL is declared in your settings.py
STATIC_URL = '/static/'
- [Django]-Replace textarea with rich text editor in Django Admin?
- [Django]-Django query where in
- [Django]-Django: Group by date (day, month, year)
0👍
The staticfiles app implements serving of static files by overriding the runserver command. We can do the same: override this command again and implement a custom handler which turns off caching.
Note that your django application must be before django.contrib.staticfiles
in INSTALLED_APPS
, otherwise your command will be ignored.
# 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]-Implementing Single Sign On (SSO) using Django
- [Django]-Get all related Django model objects
- [Django]-Django check for any exists for a query
0👍
With whitenoise, you can disable your browser to cache the static files of Django.
So first, install whitenoise
as shown below:
pip install whitenoise
Then, you must set whitenoise.runserver_nostatic
just before django.contrib.staticfiles
in INSTALLED_APPS and set WhiteNoiseMiddleware
just after SecurityMiddleware in MIDDLEWARE in settings.py
as shown below otherwise your browser still caches the static files in Django:
# "settings.py"
INSTALLED_APPS = [
...
'whitenoise.runserver_nostatic', # Here
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware', # Here
...
]
Lastly, I recommend to clear browser’s cache after setting whitenoise
following my answer here because your browser will still keep the cache of the static files of Django. *On Google Chrome, you can open the page to clear cache with Ctrl+Shift+Del which also works on Firefox. Or you can empty cache and reload the page with Ctrl+F5, Shift+F5 or Ctrl+Shift+R (Ctrl+F5 or Ctrl+Shift+R in Firefox). Or you can use the Google Chrome extension Clear Cache to clear cache
- [Django]-Passing objects from Django to Javascript DOM
- [Django]-Parsing unicode input using python json.loads
- [Django]-Django 1.9 deprecation warnings app_label
0👍
Use the never_cache
decorator from django.views.decorators.cache
to patch the default django.views.static.serve
.
For example, you could use this in your development settings file:
import django.views.static
from django.views.decorators.cache import never_cache
django.views.static.serve = never_cache(django.views.static.serve)
- [Django]-Add class to form field Django ModelForm
- [Django]-Django composite unique on multiple model fields
- [Django]-Django F expressions joined field
-1👍
This has nothing with Django, because nothing changed after I reinstall Django using pip.
This is the behavior of browser, so you just need to clear cached images files of your browser.
Ref
- [Django]-Inline in ModelForm
- [Django]-Bad request 400: nginx / gunicorn
- [Django]-How can I subtract or add 100 years to a datetime field in the database in Django?