Opened 8 years ago

Closed 8 years ago

Last modified 22 months ago

#27572 closed Cleanup/optimization (wontfix)

Static files served in development should prevent caching

Reported by: Kevin Christopher Henry Owned by: nobody
Component: contrib.staticfiles Version: 1.10
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Kevin Christopher Henry)

Currently, when Django serves static files in development with runserver and django.contrib.staticfiles it doesn't provide any cache headers. In their absence, user agents are free to cache the resources however they like. That means that when the developer updates a static resource they can't predict whether or not they will see the new version or the older cached version.

Dealing with this on the user agent side isn't always easy. For example, if you're using an embedded browser in a native app you'll probably have to create a remote debugging connection to the app and use platform-specific development tools to manipulate or disable the cache.

Since caching is a performance optimization that makes development more difficult and less predictable, I think it makes sense to disable it (via the appropriate HTTP headers) for static resources served in development.

Change History (7)

comment:1 by Tim Graham, 8 years ago

We've been thinking about replacing our own staticfile serving code with something like whitenoise (#27572). Do you know if it has a suitable option?

Last edited 8 years ago by Tim Graham (previous) (diff)

comment:2 by Kevin Christopher Henry, 8 years ago

I haven't used whitenoise before, but based on the documentation it looks like it's already doing what I proposed above:

WHITENOISE_MAX_AGE
    Default: 60 if not settings.DEBUG else 0

Time (in seconds) for which browsers and proxies should cache non-versioned files.

So, yes, a switch to whitenoise should solve this problem! I don't know how imminent that is, so I'll leave it up to you whether this is worth fixing in the meantime.

comment:3 by Tim Graham, 8 years ago

Resolution: wontfix
Status: newclosed

Great, I don't see much value in duplicating work then.

comment:4 by Mateusz Kurowski, 22 months ago

Description: modified (diff)

For future reference here is a monkey patch that works for me in development:

from functools import wraps

import django.http
import django.views.static


def no_cache_static(f):
    @wraps(f)
    def static(*a, **kw):
        response: django.http.response.HttpResponse = f(*a, **kw)
        response.headers["Cache-Control"] = "no-cache"
        return response

    return static


django.views.static.serve = no_cache_static(django.views.static.serve)

comment:5 by Kevin Christopher Henry, 22 months ago

Description: modified (diff)

(I added the description back in since it was wiped out by the last edit.)

It looks like the idea of integrating whitenoise hasn't gone anywhere since it was last mentioned in 2017, so I'm not sure the resolution makes sense anymnore.

comment:6 by Carlton Gibson, 22 months ago

This was raised again in #32891.

Closed as wontfix with ≈: 1) We want to see the caching correctly set, and 2) "Disable caching on the client" if you don't want it. 2 there is in contrast to "Dealing with this on the user agent side isn't always easy" — but I think these latter days it pretty much is... 🤷‍♀️ (Either way, the wrapper around static.serve seems pretty lightweight.)

comment:7 by Kevin Christopher Henry, 22 months ago

This issue is being discussed in the Django Forum.

Note: See TracTickets for help on using tickets.
Back to Top