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

Django向SQLite3插入POST数据遇约束错误及表单验证问题

问题根源分析
  1. 数据库约束未更新:虽然你给模型字段加了null=True,但未执行数据库迁移,SQLite表ISO22301_answer的value、name、question_id仍保留原始NOT NULL约束,导致插入空值时报错。
  2. 表单与前端数据不匹配:你的AnswerForm期望接收name和value字段,但前端单选按钮的name属性是LQ1至LQ10,POST数据中根本没有name/value字段,因此表单验证必然失败。
  3. 批量数据处理逻辑错误:页面有10个问题,你却尝试插入单条Answer记录,导致数据无法正确映射。

分步解决方案

1. 同步数据库模型与表结构

确保模型修改后更新数据库约束:

修改models.py(补充blank=True兼容表单验证)

class Answer(models.Model):
    value = models.IntegerField(null=True, blank=True)
    name = models.CharField(max_length=20, null=True, blank=True)
    question = models.ForeignKey(
        Question, on_delete=models.CASCADE, null=True, blank=True
    )

    def __str__(self):
        return f"{self.question} value is {self.value}"

执行迁移命令

python manage.py makemigrations
python manage.py migrate

2. 重构视图逻辑,批量处理前端提交的10个问题答案

前端提交的是LQ1至LQ10的键值对,需要遍历这些字段,逐个关联对应Question实例并创建Answer记录:

修改views.py

def leadership(request):
    if request.method == "POST":
        # 遍历POST中所有以LQ开头的字段(对应10个问题)
        for field_name, answer_value in request.POST.items():
            if field_name.startswith('LQ'):
                try:
                    # 根据字段名匹配对应Question(需根据你的Question模型调整匹配逻辑)
                    # 示例:假设Question模型有code字段存储LQ1/LQ2...
                    question = Question.objects.get(code=field_name)
                    # 创建Answer记录
                    Answer.objects.create(
                        name=field_name,
                        value=int(answer_value),
                        question=question
                    )
                except Question.DoesNotExist:
                    # 处理不存在的Question(可跳过或记录日志)
                    continue
        
        # 后续评分逻辑保持不变
        score_comments = create_list(results)
        score = score_comments[0]
        comments = score_comments[1]
        question_answers = score_comments[2]
        results_color = score_color(score)
        
        return render(request, "leadershipresults.html", {"shade": results_color})
    else:
        return render(request, "leadership.html")

3. 前端表单注意事项

确保单选按钮的value为数字类型(匹配Answer.value的IntegerField):

<!-- 示例LQ1的单选按钮组 -->
<div class="question">
    <p>问题1:xxx</p>
    <input type="radio" name="LQ1" value="1" id="LQ1-1">
    <label for="LQ1-1">选项1</label>
    
    <input type="radio" name="LQ1" value="2" id="LQ1-2">
    <label for="LQ1-2">选项2</label>
</div>

同时保留表单中的{% csrf_token %},Django需要它防范CSRF攻击,不能移除。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 11:28:14