Django报错NOT NULL constraint failed: Eid_Post_name.massenger_name
Django IntegrityError: NOT NULL constraint failed 排查修复
报错信息
django.db.utils.IntegrityError: NOT NULL constraint failed: Eid_Post_name.massenger_name
关联项目代码
views.py
from django.shortcuts import render from .models import Name # Create your views here. def Home(request): name_input = request.POST.get('user_name') name_in_model = Name(massenger_name=name_input,) name_in_model.save() return render(request , 'index.html')
models.py
from django.db import models from datetime import datetime # Create your models here. class Name(models.Model): massenger_name = models.CharField(max_length=50) action_time = models.DateTimeField(default=datetime.now) def __str__(self): return self.massenger_name
index.html 前端模板
<!DOCTYPE html> <html lang="en" dir="rtl"> <head> <meta charset="utf-8"> <title></title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous"> {% load static %} <link rel="stylesheet" href="{% static 'CSS/style.css' %}"> </head> <body> <div id="form"> <form class="row" method="POST"> <div class=""> <input type="textarea" class="form-control" placeholder="أكتب أسمك (مثلا/أخوكم عبدالله العتيبي)" id="text_name" name="user_name"> </div> <div class="col-auto"> <button type="submit" class="btn btn-primary mb-3" id="button">حمل الصورة</button> </div> </form> </div> </body> </html>
问题根因
报错触发逻辑是写入数据库时,设置了非空约束的massenger_name字段拿到了None值,具体来自代码的三个缺陷:
- 视图未区分HTTP请求方法:用户直接打开页面(GET请求)时,请求中没有POST表单数据,
request.POST.get('user_name')直接返回None,代码未做任何判断就执行存库 - 未做输入合法性校验:即使用户POST提交,若未填写输入框直接点提交,也会传入空值触发异常
- 表单缺少Django强制要求的CSRF令牌,正常POST提交时会先触发403权限错误
修复步骤
- 调整视图逻辑,区分请求方法,增加输入校验
替换views.py中Home视图的代码:
from django.shortcuts import render from .models import Name def Home(request): # 仅处理POST提交的存库逻辑 if request.method == "POST": name_input = request.POST.get('user_name', '').strip() # 输入非空时才写入数据库 if name_input: Name.objects.create(massenger_name=name_input) return render(request, 'index.html')
- 给表单添加CSRF令牌
在index.html的form标签内部第一行加入{% csrf_token %},修改后表单部分代码:
<form class="row" method="POST"> {% csrf_token %} <div class=""> <input type="textarea" class="form-control" placeholder="أكتب أسمك (مثلا/أخوكم عبدالله العتيبي)" id="text_name" name="user_name"> </div> <div class="col-auto"> <button type="submit" class="btn btn-primary mb-3" id="button">حمل الصورة</button> </div> </form>
- (可选配置)如果业务允许
massenger_name字段为空,可以修改模型字段增加空值允许配置,修改后需要执行python manage.py makemigrations和python manage.py migrate同步数据库结构:
massenger_name = models.CharField(max_length=50, null=True, blank=True)
常规场景下姓名字段不允许为空,优先使用前两步修复即可。
内容的提问来源于stack exchange,提问作者data data
相关产品推荐
相关产品推荐

