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

Django表单集成JavaScript添加配料时避免表单提交问题求助

问题分析与解决方案

核心问题原因

  1. JavaScript变量作用域错误:ingList函数中直接使用ingredient和quantity变量,但这两个变量是在checkdata函数内用var声明的,作用域仅限于checkdata,导致ingList执行时抛出错误,可能引发浏览器异常行为(比如误触发表单提交)。
  2. 逻辑错误导致数据无法正确存储:ingList中处理配料列表的代码逻辑混乱,未正确将配料数据写入目标textarea(myList),同时存在未定义变量list的问题。
  3. 表单字段重复:HTML中同时渲染了{{ form }}和手动编写的表单字段,导致提交时出现重复字段,可能引发后端处理异常。

分步修复代码

1. 修正HTML代码

移除重复的手动表单字段,直接使用Django表单渲染,同时确保配料输入区域结构清晰:

{% extends "base.html" %}

{% block content %}
{% load static %}
<script src="{% static 'Ingredients.js' %}"></script>
<h3><a href="{% url 'my_page' %}">BACK</a></h3>
<p>{{ user }} please fill up the form.</p>
<br>
<form action="{% url 'new_recipe' %}" method="post">
    {% csrf_token %}
    <!-- 直接使用Django表单渲染,避免重复字段 -->
    <div class="form-group">
        {{ form.recipe_name.label_tag }} {{ form.recipe_name }}
        <br><br>
        {{ form.description.label_tag }} {{ form.description }}
        <br><br>
        {{ form.cooking_time.label_tag }} {{ form.cooking_time }}
        <br><br>
        <fieldset>
            <legend>Enter Ingredients</legend>
            <label for="ingredient">Ingredient name :</label>
            <input type="text" id="ingredient" name="temp_ingredient">
            <span>
                <label for="quantity">Enter the quantity:</label>
                <input type="text" id="quantity" name="temp_quantity">
            </span><br><br>
            <button id="add" type="button" onclick="checkdata()">Add Ingredient</button>
        </fieldset>
        <br>
        <!-- 将配料列表绑定到model的ingredients字段 -->
        {{ form.ingredients.label_tag }}
        <textarea id="myList" name="ingredients" readonly></textarea>
        <br><br>
        {{ form.preparation.label_tag }} {{ form.preparation }}
        <br><br>
    </div>
    <button type="submit">Add Recipe</button>
</form>
{% endblock content %}

2. 修正JavaScript代码

修复变量作用域问题,正确处理配料列表的存储逻辑:

function checkdata() {
    // 获取输入元素
    const ingredientInput = document.getElementById("ingredient");
    const quantityInput = document.getElementById("quantity");
    const ingredient = ingredientInput.value.trim();
    const quantity = quantityInput.value.trim();

    // 验证输入
    if (!ingredient) {
        alert("Please enter the ingredient");
        ingredientInput.focus();
        return false;
    }
    if (!quantity) {
        alert("Please enter the quantity");
        quantityInput.focus();
        return false;
    }

    // 调用添加函数,传递验证后的值
    addIngredient(ingredient, quantity);
}

function addIngredient(ingredient, quantity) {
    const ingredientsTextarea = document.getElementById("myList");
    // 读取现有配料列表,解析为数组
    let ingredients = [];
    if (ingredientsTextarea.value) {
        try {
            ingredients = JSON.parse(ingredientsTextarea.value);
        } catch (e) {
            // 如果解析失败,重置为空数组
            ingredients = [];
        }
    }
    // 添加新配料
    ingredients.push({ name: ingredient, quantity: quantity });
    // 将数组转换为JSON字符串存回textarea
    ingredientsTextarea.value = JSON.stringify(ingredients);
    
    // 清空输入框
    document.getElementById("ingredient").value = "";
    document.getElementById("quantity").value = "";
}

3. 后端处理(可选优化)

在Django的视图函数中,接收JSON格式的配料数据后,可转换为可读性更好的字符串存储:

import json
from django.shortcuts import render, redirect
from .forms import RecipeForm

def new_recipe(request):
    if request.method == 'POST':
        form = RecipeForm(request.POST)
        if form.is_valid():
            # 解析JSON配料数据
            ingredients = json.loads(form.cleaned_data['ingredients'])
            # 转换为易读的字符串,比如"鸡蛋 2个,面粉 100g"
            ingredients_str = ", ".join([f"{item['name']} {item['quantity']}" for item in ingredients])
            # 保存到模型
            recipe = form.save(commit=False)
            recipe.ingredients = ingredients_str
            recipe.user_name = request.user
            recipe.save()
            return redirect('my_page')
    else:
        form = RecipeForm()
    return render(request, 'new_recipe.html', {'form': form})

关键修复点说明

  • 阻止误提交:确保添加按钮的type="button",同时JS函数内无未捕获错误,避免浏览器异常触发表单提交。
  • 变量作用域:在checkdata中验证后将值传递给addIngredient,避免跨函数访问未定义变量。
  • 正确存储配料:使用JSON格式将配料列表存储到textarea,后端可解析后转换为友好格式存储。
  • 避免重复字段:移除手动编写的表单字段,直接使用Django表单渲染,确保数据提交的正确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 22:14:56