2

I have a django template with a class-based DetailView associated to it. I've over-ridden the get_context_data method of the DetailView, using it to pass some required context variables that I display in the template (essentially an image). That's all I've done.

How do I ensure this particular django template of mine is never cached by any browser? Wading through various sources tells me I need to over-ride the HttpResponse in the dispatch method to accomplish no-cache?

I understand that I'll need to set the Cache-Control, Pragma, Expiry etc. I've just been unable to make headway regarding whether to (or how to) over-ride the dispatch method. Can someone give me a simple clarificational example of how they would go about implementing no-cache for such a template?

Moe Far
  • 2,742
  • 2
  • 23
  • 41
Hassan Baig
  • 15,055
  • 27
  • 102
  • 205

1 Answers1

5

Firstly, it's the view rather than the template that you want to control HTTP caching on.

The template is just a chunk of HTML that can be rendered by any view, the view is what sends an HTTP Response to the web browser.

Django comes with some handy view decorators for controlling the HTTP headers returned by a view:
https://docs.djangoproject.com/en/1.9/topics/cache/#controlling-cache-using-other-headers

You can find this simple example in the docs:

from django.views.decorators.cache import never_cache

@never_cache
def myview(request):
    # ...

If you are using 'class-based' views rather than simple functions then there's a gist here with an example of how to convert this decorator into a view Mixin class:

from django.utils.decorators import method_decorator
from django.views.decorators.cache import never_cache


class NeverCacheMixin(object):
    @method_decorator(never_cache)
    def dispatch(self, *args, **kwargs):
        return super(NeverCacheMixin, self).dispatch(*args, **kwargs)

...which you'd use in your project like:

from django.views.generic.detail import DetailView


class ArticleView(NeverCacheMixin, DetailView):
    template_name = "article_detail.html"
    queryset = Article.objects.articles()
    context_object_name = "article"
Anentropic
  • 32,188
  • 12
  • 99
  • 147
  • Doing some research on never cache shows results where it seems it's not enough for all browsers (e.g.: http://stackoverflow.com/a/2095648/4936905). Seems I should manually set `Pragma` and some values in `Cache-Control`? What would you say, in your experience? – Hassan Baig Feb 13 '16 at 23:59
  • Which Django version are you using? following up on the comments on that page, the extra stuff proposed seems to have been merged into Django 1.8. – Anentropic Feb 15 '16 at 10:03
  • Oh I'm on pre 1.8. Maybe you could add a qualification for pre.1.8 in your answer? (for completeness). – Hassan Baig Feb 15 '16 at 13:15