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

Django表单提交报NOT NULL约束失败: posts_subscribe.firstname

报错原因
  • 表单输入控件未配置name属性:表单通过POST提交数据时,后端是根据控件的name属性来匹配对应取值的,id属性仅用于前端DOM绑定、label关联,不参与表单值提交。当前模板内所有input标签都缺少name属性,直接导致后端request.POST.get()拿不到任何用户输入,所有字段返回值都是None。
  • 模型字段约束理解偏差:你给firstname、secondname加的blank=True仅作用于Django自带的表单验证环节,不会改变数据库层面的非空约束。Django模型字段默认null=False,也就是数据库表的对应字段禁止存入NULL值,当你把取到的None传给firstname字段执行save操作时,就会触发题目中的NOT NULL约束报错。
解决步骤

1. 修复模板表单,为所有input补充对应name属性

给四个输入框分别添加和后端取值名一致的name属性,修改后的表单核心代码如下:

<form method="POST" enctype="multipart/form-data" action="subscribe">
    {% csrf_token %}
    <div class="mb-3 mx-5">
        <label for="firstname" class="form-label">First Name</label>
        <input type="text" name="firstname" class="form-control form-control-lg" id="firstname" placeholder="firstname">
    </div>
    <div class="mb-3 mx-5">
        <label for="secondname" class="form-label">Second Name (Optional)</label>
        <input type="text" name="secondname" class="form-control form-control-lg" id="secondname" placeholder="secondname">
    </div>
    <div class="mb-3 mx-5">
        <label for="email" class="form-label">Email</label>
        <input type="email" name="email" class="form-control form-control-lg" id="email" placeholder="example@example.com">
    </div>
    <div class="mb-3 mx-5">
        <label for="phonenumber" class="form-label">Phonenumber</label>
        <input type="number" name="phonenumber" class="form-control form-control-lg" id="phonenumber" placeholder="0712345678">
    </div>
    <div class="mb-3 mx-5">
        <button type="submit" class="btn-primary">Subscribe</button>
    </div>     
</form>

2. 修正模型字段配置,匹配业务规则

如果firstname、secondname确实允许用户留空,需要补充null=True开放数据库层面的空值存储权限;另外手机号不建议使用IntegerField存储,会出现长度溢出、前导0被自动清除的问题,建议改为CharField,修改后的模型代码如下:

class Subscribe(models.Model):
    firstname = models.CharField(max_length=30, blank=True, null=True)
    secondname = models.CharField(max_length=30, blank=True, null=True)
    email = models.CharField(max_length=30)
    phonenumber = models.CharField(max_length=15)

3. 执行数据库迁移同步表结构

修改完模型后,在项目根目录终端执行以下两条命令,将模型改动同步到数据库表:

python manage.py makemigrations
python manage.py migrate

可选优化:增加后端取值兜底

可以在调用request.POST.get()时设置空字符串作为默认值,避免极端场景下取值为None的问题:

def subscribe(request):
    if request.method == 'POST':
        firstname = request.POST.get('firstname', '')
        secondname = request.POST.get('secondname', '')
        email = request.POST.get('email', '')
        phonenumber = request.POST.get('phonenumber', '')
        en = Subscribe(firstname=firstname, secondname=secondname, email=email, phonenumber=phonenumber)
        en.save()
        return redirect('/')
    return render(request, 'subscribe.html')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:18:30