我有一个应用程序,其中列出了一堆表单 - 它将 csrf_token 加载到每个表单中。
每个表单都是一个简单的下拉菜单,用于为列表中的每个项目选择“颜色”。
我有一个
ListView
,它返回一个放置对象列表,如下所示:
{% for placement in placements %}
{% include 'placements/snippets/placement_update_form.html' %}
{% endfor %}
placement_update_form.html
看起来像这样:
<form id="placementUpdateForm" action="{{ placement.get_update_url }}" method="post" hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
<input type="hidden" name="id" value="{{ placement.id }}">
<label for="color">Color</label>
<select name="color" id="color{{ placement.pk }}" class="form-select" hx-post="{% url 'placements:placement-update' placement.pk %}" hx-target="closest #placementUpdateForm">
<option value="" {% if not placement.color %}selected{% endif %}>Default</option>
{% for value, display_name in placement_colors %}
<option value="{{ value }}" {% if value == placement.color %}selected{% endif %}>{{ display_name }}</option>
{% endfor %}
</select>
</form>
我正在使用 HTMX 将数据
POST
发送到后端的UpdateView
;它重定向到一个 success_url
,即一个 DetailView
,它只是返回 placement_update_template
并替换 DOM 中的确切项目。
它有效 - 一次。 first
POST
可以正常工作并按预期保存颜色。模板在 DOM 中被替换,但如果您选择不同的颜色(触发第二个POST
),则会失败。
此外,如果我尝试更改任何 other 表单的颜色 - 它也会失败并出现相同的错误。
所有后续
POST
请求都给我这个错误:
Forbidden (CSRF token from the 'X-Csrftoken' HTTP header incorrect.): /placements/1/update/
通过 HTMX 提交这些表单时处理此问题的最佳方法是什么?
这是一个常见问题,最简单的处理方法是按以下方式使用 hx-headers:
<body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
...
</body>
参考: https://django-htmx.readthedocs.io/en/latest/tips.html#make-htmx-pass-the-csrf-token