Advanced Cache Control¶
Page-specific cache control¶
The WagtailCacheMixin
also gives you the option to add a
custom Cache-Control header via cache_control
, which can be a dynamic
function or a string:
from wagtailcache.cache import WagtailCacheMixin
class MyPage(WagtailCacheMixin, Page):
cache_control = 'no-cache'
...
Setting this to contain no-cache
or private
will tell wagtail-cache
not to cache this page. You could also set it to a custom value such as
“public, max-age=3600”. It can also be a function:
from wagtailcache.cache import WagtailCacheMixin
class MyPage(WagtailCacheMixin, Page):
def cache_control(self):
return 'no-cache'
...
Not caching views or URLs¶
Across the entire Django site, Wagtail Cache will never cache a response that has a
Cache-Control
header containing no-cache
or private
. Adding this
header to any response will cause it to be skipped.
To explicitly not cache certain views or URL patterns, you could also wrap them
with the nocache_page
decorator, which adds the Cache-Control: no-cache
header to all responses of that view or URL pattern. To use with a view:
from wagtailcache.cache import nocache_page
@nocache_page
def myview(request):
...
Or on a URL pattern:
from wagtailcache.cache import nocache_page
...
url(r'^url/pattern/$', nocache_page(viewname), name='viewname'),
...
When using the Wagtail Cache middleware, the middleware will detect CSRF tokens and will only cache
those responses on a per-cookie basis. So Wagtail Cache should work well with CSRF tokens 🙂.
But if you still experience issues with CSRF tokens, use the mixin, the nocache_page
decorator,
or set the Cache-Control
header to no-cache
on the response to guarantee that it will
never be cached. If you are using the cache_page
decorator instead of the middleware, you
must use the mixin or set the Cache-Control
header on responses with CSRF tokens to avoid
getting 403 forbidden errors.
Using a separate cache backend¶
For complex sites, it may be desirable to use a separate cache backend only for the page cache, so that purging the page cache will not affect other caches:
WAGTAIL_CACHE_BACKEND = 'pagecache'
CACHES = {
'default': {
...
},
'pagecache': {
...
}
}
Only cache specific views¶
The wagtail-cache middleware will attempt to cache ALL responses that appear to be cacheable (meaning the response does not contain a ‘no-cache’/’private’ Cache-Control header, the request method is GET or HEAD, the response status code is 200, 301, 302, 404, the response did not set a cookie, the page is not in preview mode, a user is not logged in, and many other requirements).
To only cache specific views, remove the middleware and use the cache_page
decorator on views or URLs.
Alternatively, to continue using the middleware but explicitly not cache certain views or URLs, wrap those
views or URLs with the nocache_page
decorator.
Note that when using the cache_page
decorator, it is not possible to cache Wagtail page 404s or redirects. Only the
middleware is able to cache those responses.
Caching wagtail pages only¶
Most likely you will want this on all of your wagtail pages, so you will have to
replace the inclusion of wagtail_urls
in your project’s urls.py
. You
will need to change from this:
from django.conf.urls import url
url(r'', include(wagtail_urls)),
To this:
from django.conf.urls import url
from django.contrib.auth import views as auth_views
from wagtail.urls import serve_pattern, WAGTAIL_FRONTEND_LOGIN_TEMPLATE
from wagtail import views as wagtail_views
from wagtailcache.cache import cache_page
# Copied from wagtail.urls:
url(r'^_util/authenticate_with_password/(\d+)/(\d+)/$', wagtail_views.authenticate_with_password,
name='wagtailcore_authenticate_with_password'),
url(r'^_util/login/$', auth_views.LoginView.as_view(template_name=WAGTAIL_FRONTEND_LOGIN_TEMPLATE),
name='wagtailcore_login'),
# Wrap the serve function with wagtail-cache
url(serve_pattern, cache_page(wagtail_views.serve), name='wagtail_serve'),
Caching specific wagtail page models only¶
You can also use the decorator on specific wagtail pages. It is helpful in Wagtail sites where the requirement is not to cache all pages:
from django.utils.decorators import method_decorator
from wagtailcache.cache import cache_page, WagtailCacheMixin
@method_decorator(cache_page, name='serve')
class MyPage(WagtailCacheMixin, Page):
...
Caching views¶
You can also use the decorator on views:
from wagtailcache.cache import cache_page
@cache_page
def myview(request):
...
To use it on class-based views:
from django.utils.decorators import method_decorator
from wagtailcache.cache import cache_page
@method_decorator(cache_page, name='dispatch')
class MyView(TemplateView):
...