开发者

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!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜