使用HTMX实现按钮修改Django布尔值时的403错误排查
问题分析与修复方案
1. 403错误根源:缺失CSRF令牌验证
Django默认启用CSRF保护,HTMX发起的POST请求必须携带CSRF令牌才能通过验证,你的按钮未添加相关参数,导致请求被拦截。
- 修复:在按钮上添加CSRF令牌头部参数
<button type="button" class="btn btn-success m-3" hx-post="{% url 'procurement:po_accept' order.pk %}" hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' > Accept </button>
2. 模型字段名不匹配
PurchaseOrder模型定义的布尔字段是approved,但视图po_accept中错误修改了不存在的approved_accounting字段,会触发数据库操作异常。
- 修复:将视图中的字段名修正为
approvedorder.approved = True
3. 视图渲染缺失模板参数
po_accept视图的render函数缺少模板路径参数,正确调用格式应为render(request, 模板文件名, context),当前写法会抛出异常。
- 修复:创建片段模板并补充参数
先新建procurement/po_accept_response.html作为响应模板,再修改视图:@require_http_methods(['POST']) def po_accept(request, pk): order = get_object_or_404(PurchaseOrder, pk=pk) order.approved = True order.save() context = {'order': order} return render(request, 'procurement/po_accept_response.html', context)
4. HTMX请求后页面无更新逻辑
当前点击按钮后,后端未返回需更新的内容,页面状态不会变化。需通过响应模板返回更新后的状态,并配置HTMX的目标替换规则。
- 示例
po_accept_response.html内容:<span class="text-success">已批准</span> - 修改原页面的按钮容器,添加HTMX替换规则:
<div id="approval-status-{{ order.pk }}"> {% if not order.approved %} <button type="button" class="btn btn-success m-3" hx-post="{% url 'procurement:po_accept' order.pk %}" hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-target="#approval-status-{{ order.pk }}" hx-swap="innerHTML" > Accept </button> {% else %} <span class="text-success">已批准</span> {% endif %} </div>
5. 视图遗漏必要导入
po_accept视图使用了get_object_or_404但未导入,会触发NameError。
- 修复:在views.py顶部补充导入
from django.shortcuts import get_object_or_404, render
内容的提问来源于stack exchange,提问作者Markus G.
相关产品推荐
相关产品推荐

