如何在包含有限上下文的 Django 模板中使用 csrf_token

How to use csrf_token in django template included with limited context

Django 模板允许您包含其他模板来组成您的页面。当您想要呈现整个页面,但可能想使用 AJAX 重新加载其中的一部分,并且不想将所有呈现逻辑移动到 javascript(或更糟:复制到 javascript).

包含模板可以如下所示:

{% include "template.html" %}

但是,如果该模板可能被不同的视图使用,则您的上下文很可能不仅仅是该模板上下文的超集。所以 Django 也允许您为模板指定上下文。

因为我想避免在通过包含在另一个模板中呈现模板时意外引入不同的行为,以及当模板作为视图的主要模板呈现时,使用 only 选项以避免它访问父模板的上下文。

所以我的包含看起来像这样:

{% include "sub_template.html" foo=sub_context.foo bar=sub_context.bar only %}

但是,添加 only 会导致问题:{% csrf_token %} 在该模板中不再有效,因为我猜 Django 的一些隐藏魔法已被排除。

Django 记录的错误是

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.

父模板RequestContext渲染的,当子模板渲染为主模板,不包含时,不会出现错误.

这个问题最明显的解决方法是不使用 includeonly 选项,这似乎很遗憾。有没有更好的方法来解决这个问题?

我遇到了同样的问题,并且同意不使用 only 不是一个理想的解决方案。

事实证明 {{csrf_token}} 在父模板中工作得很好,因此您可以使用它来将裸体 csrf_token 发送到包含的模板:

{% include "sub_template.html" foo=sub_context.foo csrf_token=csrf_token only %}

然后 {% csrf_token %} 标签在另一侧工作正常,并使用该值输出完整的隐藏输入元素。而且您仍然可以获得仅在包含中使用的优势。

我的答案是通过试验这个问题的答案得出的: Django's {{ csrf_token }} is outputting the token value only, without the hidden input markup