How do I disable Django per-view caching when debug is on?
I've written a bunch of views in Django that use per-page caching. The code looks like this:
from django.http import HttpResponse
from django.views.decorators.cache import cache_pa开发者_如何转开发ge
@cache_page(60 * 5)
def view_page(request):
return HttpResponse('hello world')
This works wonderfully, but is a pain during testing. How do I only do caching with debug off?
Check out django's dummy cache backend.
So for your development enviroment you should set your cache backend to django.core.cache.backends.dummy.DummyCache
You could conditionally decorate your view.
from django.http import HttpResponse
from django.views.decorators.cache import cache_page
from django.conf import settings
def view_page(request):
return HttpResponse('hello world')
if not settings.DEBUG:
view_page = cache_page(60 * 5)(view_page)
or perhaps this would work.
from django.http import HttpResponse
from django.views.decorators.cache import cache_page, never_cache
from django.conf import settings
production_cache = lambda func: cache_page(60 * 5)(func) if settings.DEBUG else never_cache(func)
@production_cache
def view_page(request):
return HttpResponse('hello world')
In fact it can be done without a lambda
from django.http import HttpResponse
from django.views.decorators.cache import cache_page, never_cache
from django.conf import settings
production_cache = cache_page(60 * 5) if not settings.DEBUG else never_cache
@production_cache
def view_page(request):
return HttpResponse('hello world')
Using @StephenPaulger's method, it will also prevent Django from setting the cache related headers like Expires
. If you're working with another system that interprets these headers and keeps it's own cache as long as the date in the Expires
header isn't reached, this can be pretty annoying while developing.
If you use never_cache
, Django will set the Expires
header to the current time of the request, so the document would be outdated right away.
You can create this in a separate file in your project:
from django.conf import settings
from django.views.decorators.cache import (
cache_page as django_cache_page, never_cache
)
if settings.DEBUG:
cache_func = lambda seconds: never_cache
else:
cache_func = django_cache_page
def cache_page(seconds):
return cache_func(seconds)
Then you can import this custom cache_page
function instead of the native Django one and use it the same way. This if
statement would only be executed once when the module is imported.
If you have separate settings files (for development and production) you can even make it more efficient by putting the functions in the settings files. So for the development settings you would do this:
from django.views.decorators.cache import never_cache
CACHE_FUNC = lambda seconds: never_cache
And in the production settings you would put:
from django.views.decorators.cache import cache_page
CACHE_FUNC = cache_page
Then in a separate file in your project:
from django.conf import settings
def cache_page(seconds):
return settings.CACHE_FUNC(seconds)
With this method, the CACHE_FUNC
would be defined only once during the startup of Django. So no impact on performance, and no annoying Expires
headers during development!
精彩评论