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

Django IntegrityError求助:NOT NULL约束失败(todo_todo.name)

解决Django IntegrityError: NOT NULL constraint failed问题

问题场景

提交表单时触发错误:IntegrityError at /todo NOT NULL constraint failed: todo_todo.name,未使用外键,仅将name字段定义为带默认值的CharField。

相关代码如下:

models.py

from django.db import models

class ToDo(models.Model):
    name = models.CharField(max_length=200, default=" ")

views.py

from django.shortcuts import render, HttpResponse
from .models import ToDo

def home(request):
    data = request.POST.get('name')
    print(data)
    context = {'data':data}
    return render(request, "todo/home.html", context)

def todo(request):
    name = request.POST.get('name')
    todo = ToDo(name=name)
    todo.save()
    context = {'names' : todo}
    return render(request, "todo/todo.html", context)

todo.html

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
</head>
<body>
    <h1>TO DO LIST</h1>
    <form method="post" action="/todo">
        {% csrf_token %} 
        <label for="name"> </label>
        <input type="text" name="name" id="name">
        <br>
        <button type="submit">Add Task</button>
    </form>
    {% for x in names %}
    <h4>{{ x.name }}</h4>
    {% endfor %}
</body>
</html>

原因分析

  1. 空值传递触发约束:当表单空提交或请求为GET时,request.POST.get('name')返回None。显式将None赋值给name字段时,会覆盖模型的默认值,而CharField默认null=False,数据库不允许存储NULL值,因此触发非空约束错误。
  2. 模板循环对象错误:视图传递单个ToDo对象给names变量,但模板用{% for %}循环遍历,单个对象无法被迭代,会引发额外异常。
  3. 未区分请求方法:直接访问/todo时是GET请求,此时request.POST为空,执行todo.save()直接触发错误。

解决方案

1. 修复视图逻辑

修改views.py中的todo视图,区分请求方法并处理空值:

def todo(request):
    if request.method == 'POST':
        # 给GET方法设置默认空字符串,避免返回None
        name = request.POST.get('name', '')
        # 空字符串则使用模型默认值,不传递name参数
        todo = ToDo(name=name) if name.strip() else ToDo()
        todo.save()
    # 传递所有任务查询集给模板,支持循环遍历
    context = {'names': ToDo.objects.all()}
    return render(request, "todo/todo.html", context)

2. 优化模型字段(可选)

如果允许提交空名称任务,可给name字段添加blank=True,允许表单层面的空值:

class ToDo(models.Model):
    name = models.CharField(max_length=200, default=" ", blank=True)

3. 验证模板循环

确保模板接收的是查询集而非单个对象,上述视图中context = {'names': ToDo.objects.all()}已解决此问题,模板可正常遍历所有任务。

测试验证

  • 空表单提交时,自动使用模型默认值创建任务;
  • 输入内容提交时,保存输入的任务名称;
  • 直接访问/todo时,正常显示任务列表,无错误触发。

内容的提问来源于stack exchange,提问作者S K M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 14:43:23