Search code examples
djangoheaderresponsecache-control

Cache-Control not being set in response header


I am trying to optimize my Django web application by leveraging browser caching. I set a Cache-Control header for max-age equal to a year in my home view function returned response. When I load up my site however, and check the response header of some of the images on my home page, the cache-control header isn't there. I tried two different methods of setting the response header. First I tried using Django's built in cache-control decorator. I also tried simply taking the rendered response, and setting the header in my view function before its return statement. Are static images cached differently ?

View Function

def view_home(request, page=None):
    # FIND THE HOME PAGE IF WE DO NOT HAVE ONE
    # IF NOT FOUND RETURN 404
    if not page:
        try:
            page = WebPage.objects.get(template='home')

        except WebPage.DoesNotExist:
            raise Http404

    try:
        billboards = Billboard.get_published_objects()

    except Exception as e:
        logging.error(e)
        billboards = None

    project_types = ProjectType.get_published_objects()
    budgets = Budget.get_published_objects()
    deadlines = Deadline.get_published_objects()
    contact_descriptions = ContactDescription.get_published_objects()

    contact_form = ContactForm(type_list=project_types, budget_list=budgets,
                               deadline_list=deadlines, description_list=contact_descriptions)

    context = {'page': page, 'billboards': billboards, 'contact_form': contact_form}
    set_detail_context(request, context)

    template = 'home.html'

    # Add Cache control to response header
    expiry_date = datetime.datetime.now() + datetime.timedelta(days=7)
    response = render(request, template, context)

    response['Cache-Control'] = 'max-age=602000'
    response['Expires'] = expiry_date

    return response

Solution

  • It sounds like you're setting the headers on a per-view basis. But those views are handling specific URLs, which presumably are not the URLs for your static image files. So it won't have any effect on those.

    How you set the headers for your static files depends on how you're serving them.

    1. The most straightforward solution is to use the whitenoise app. This serves static files from Django in the same way in both development and production, and has a setting to control the max-age.

    2. If you're using an external server (e.g. ngnix or Apache) you'll need to configure it to set any custom headers. It doesn't have anything to do with Django.

    3. If you're using the Django development server you'll have to opt out of having it handle the static files automatically, and instead use a custom view that sets the headers. (Or you could just not bother when using the development server.)