Django templates allow you to include other templates to compose your page. This is particularly useful when you want to render the entire page, but might want to re-load part of it using AJAX, and don't want to move all render logic into javascript (or worse: duplicate it in javascript).
Including a template can look like this:
{% include "template.html" %}
However, if that template might be used by different views, it's likely that your context isn't just a superset of the context for that template. So Django lets you specify the context for the template too.
Because I want to avoid accidentally introducing different behaviour when the template is rendered by being included in another template, and when the template is rendered as the primary template for a view, it also makes sense to me to use the only
option to avoid it accessing the parent template's context.
So my include looks like this:
{% include "sub_template.html" foo=sub_context.foo bar=sub_context.bar only %}
However, adding that only
causes a problem: {% csrf_token %}
no longer works in that template because I guess some of the hidden magic that Django does has been excluded.
The error that Django logs is
UserWarning: A {% csrf_token %} was used in a template, but the context did not provide the value. This is usually caused by not using RequestContext.
The parent template is rendered with a RequestContext
, and when the sub template is rendered as the primary template, and not included, the error doesn't occur.
The most obvious work-around to this problem is to not using the only
option to include
, which seems a shame. Is there a better way of working around this problem?