Django报错IntegrityError:NOT NULL约束失败(app_staff_notification.message)
Django员工通知功能IntegrityError问题排查与解决
错误情况
访问路径/Hod/Staff/Save_Notification时触发IntegrityError,错误提示:NOT NULL constraint failed: app_staff_notification.message,此前曾终止过异常的模型迁移操作。
相关代码
models.py
class Staff_Notification(models.Model): staff_id = models.ForeignKey(Staff, on_delete=models.CASCADE) message = models.TextField() created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return self.staff_id.admin.first_name
urls.py
path('Hod/Staff/Send_Notification', Hod_Views.STAFF_SEND_NOTIFICATION, name='staff_send_notification'), path('Hod/Staff/Save_Notification', Hod_Views.SAVE_STAFF_NOTIFICATION, name='save_staff_notification'),
Hod_Views.py
def SAVE_STAFF_NOTIFICATION(request): if request.method=='POST': staff_id = request.POST.get('staff_id') message = request.POST.get('message') staff = Staff.objects.get(admin = staff_id) notification = Staff_Notification( staff_id = staff, message = message, ) notification.save() return redirect('staff_send_notification')
staff_notification.html
{% extends 'base.html' %} {% block content %} <div class="content container-fluid"> <div class="page-header"> <div class="row align-items-center"> <div class="col"> <h3 class="page-title">Staff</h3> <ul class="breadcrumb"> <li class="breadcrumb-item"><a href="index.html">Dashboard</a></li> <li class="breadcrumb-item active">Staffs</li> </ul> </div> <div class="col-auto text-right float-right ml-auto"> <!-- Button trigger modal --> <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModalCenter">View All Notifications </button> <!--a href="#" class="btn btn-primary mr-2"--> </div> </div> </div> {% include 'includes/messages.html' %} <div class="row"> <div class="col-sm-12"> <div class="card card-table"> <div class="card-body"> <div class="table-responsive"> <table id="table_id" class="table table-hover table-bordered table-center mb-0"> <thead> <tr> <th>ID</th> <th>Name</th> <th>Email</th> <th class="text-right">Action</th> </tr> </thead> <tbody class="table-group-divider"> {% for i in staff %} <tr> <td>{{i.id}}</td> <td> <h2 class="table-avatar"> <a href="student-details.html" class="avatar avatar-sm mr-2"><img class="avatar-img rounded-circle" src="/{{i.admin.profile_pic}}" alt="User Image"></a> <a href="student-details.html">{{i.admin.first_name}} {{i.admin.last_name}}</a> </h2> </td> <td>{{i.admin.email}}</td> <td class="text-right"> <button type="button" class="btn btn-success" data toggle="modal" data-target="#sendnotification-{{forloop.counter}}">Send Notification </button> </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </div> </div> </div> <!-- Modal --> {% for i in staff %} <div class="modal fade" id="sendnotification-{{forloop.counter}}" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle1" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLongTitle1">Send Staff Notification To {{i.admin.first_name}} {{i.admin.last_name}}</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <form method="post" action="{% url 'save_staff_notification' %}"> {% csrf_token %} <div class="form-group"> <input type="text" class="form-control" name="message"> <input type="text" class="form-control" name="staff_id" value="{{i.admin.id}}" hidden> </div> <button type="submit" class="btn btn-primary">Send Notification</button> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> </div> </div> </div> </div> {% endfor %} {% endblock %}
问题排查
- 字段非空约束触发:
message字段在模型中定义为TextField()(默认非空),但保存时传入了NULL值,导致数据库约束校验失败。 - 前端表单问题:message输入框未添加必填校验,用户可空提交;按钮的
data toggle属性缺少连字符(应为data-toggle),可能导致弹窗交互异常。 - 视图层校验缺失:未对
message是否为空做判断,直接存入数据库。 - 迁移异常残留:此前终止迁移可能导致数据库表结构与模型定义不一致,比如
message字段在数据库中被设置为允许空值。
解决方案
1. 修复前端表单
- 给message输入框添加
required属性,强制用户输入:<input type="text" class="form-control" name="message" required> - 修正按钮的
data toggle为data-toggle,确保弹窗正常触发:<button type="button" class="btn btn-success" data-toggle="modal" data-target="#sendnotification-{{forloop.counter}}">Send Notification</button>
2. 增强视图层校验逻辑
在保存通知前,校验message是否为空,同时修正员工查询的字段匹配:
def SAVE_STAFF_NOTIFICATION(request): if request.method=='POST': staff_id = request.POST.get('staff_id') message = request.POST.get('message', '').strip() # 校验消息非空 if not message: messages.error(request, "通知消息不能为空") return redirect('staff_send_notification') try: # 通过admin的ID查询对应的Staff对象 staff = Staff.objects.get(admin__id=staff_id) notification = Staff_Notification( staff_id=staff, message=message ) notification.save() messages.success(request, "通知发送成功") except Staff.DoesNotExist: messages.error(request, "指定员工不存在") return redirect('staff_send_notification')
3. 修复模型迁移异常
确保数据库表结构与模型定义一致:
- 查看当前迁移状态:
python manage.py showmigrations - 重新应用未完成的迁移:
python manage.py migrate - 若迁移文件损坏,删除
migrations目录下除__init__.py外的所有文件,重新生成并同步:python manage.py makemigrations python manage.py migrate --fake-initial - 手动确认数据库中
app_staff_notification表的message字段为NOT NULL约束。
内容的提问来源于stack exchange,提问作者Deepti Mhatre
相关产品推荐
相关产品推荐

