You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加JS后Django表单无法识别提交按钮,跳转异常求助

解决Django表单延迟提交后无法识别提交按钮的问题

问题根源

当使用JavaScript的form.submit()方法提交表单时,浏览器不会自动将触发提交的按钮的name和value包含到POST数据中,而Django后端正是通过检测request.POST里的按钮name来区分不同操作的,所以会出现无法识别点击按钮的情况。另外你代码里还有个笔误:模板中按钮的name是add_ingredient,但视图里判断的是add_ingredients(多了个s),这本来就会导致原逻辑异常,需要先修正。

解决方案

通过添加隐藏输入框存储点击的按钮标识,再在延迟提交时将该标识传入后端,具体步骤如下:

1. 修改模板表单,添加隐藏输入框

在表单的{% csrf_token %}下方添加一个隐藏输入,用来存储触发提交的按钮名称:

<form id="form" class="form" method="post" action="{% url 'core:add_ingredient' menu_item.id %}">
    {% csrf_token %}
    <!-- 添加隐藏输入框 -->
    <input type="hidden" id="submit_action" name="submit_action" value="">
    {{ form.as_p }}
    <div class="button-container">
        <button id="another-ingredient-button" type="submit" name="add_ingredient">Add Another Ingredient</button>
        <button type="submit" name="substitute">Add Substitute</button>
        <button class="done" type="submit" name="done">Done</button>
    </div>
</form>

2. 修改JavaScript代码,记录触发按钮

在表单的submit事件中,获取触发提交的按钮,将其name存入隐藏输入框,再执行延迟提交:

const alertBox = document.getElementById('alert-box')
const form = document.getElementById('form')
const submitActionInput = document.getElementById('submit_action')

form.addEventListener('submit', (e) => {
    // 获取触发提交的按钮
    const submitButton = e.submitter;
    if (submitButton) {
        submitActionInput.value = submitButton.name;
    }

    e.preventDefault();
    alertBox.style.display = 'block';

    setTimeout(() => {
        form.submit();
        alertBox.style.display = 'none';
    }, 1000);
});

3. 修正Django视图逻辑

先修正笔误,再同时兼容原按钮name和新的隐藏字段,确保两种提交方式都能识别:

form = MenuItemForm(request.POST or None, request.FILES or None)
if request.method != 'POST':
    form = MenuItemForm()
else:
    # 获取提交动作标识,优先取隐藏字段,兼容原按钮提交
    submit_action = request.POST.get('submit_action')
    # 修正笔误:模板里是add_ingredient,不是add_ingredients
    if 'add_ingredient' in request.POST or submit_action == 'add_ingredient':
        if form.is_valid():
            menu_item = form.save(commit=False)
            menu_item.menu = menu_instance
            menu_item.save()
            return redirect('core:add_ingredient', menu_item_id=menu_item.id)
    elif 'substitute' in request.POST or submit_action == 'substitute':
        # 补充substitute对应的处理逻辑
        if form.is_valid():
            menu_item = form.save(commit=False)
            menu_item.menu = menu_instance
            menu_item.save()
            # 替换为substitute对应的跳转视图
            return redirect('core:add_substitute', menu_item_id=menu_item.id)
    elif 'done' in request.POST or submit_action == 'done':
        if form.is_valid():
            menu_item = form.save(commit=False)
            menu_item.menu = menu_instance
            menu_item.save()
            return redirect('core:edit_menu')

额外说明

  • e.submitter是HTML5新增的属性,可直接获取触发提交的按钮,若需兼容旧浏览器,可改为监听每个提交按钮的click事件来记录按钮名称:
    // 给所有submit按钮加点击监听
    document.querySelectorAll('button[type="submit"]').forEach(btn => {
        btn.addEventListener('click', () => {
            submitActionInput.value = btn.name;
        });
    });
    
  • 你原视图中没有处理substitute按钮的逻辑,需要补充对应的跳转或业务代码,否则点击该按钮会默认执行done的逻辑。

内容的提问来源于stack exchange,提问作者JimmyFl0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 12:50:23