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

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">&times;</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 %}

问题排查

  1. 字段非空约束触发:message字段在模型中定义为TextField()(默认非空),但保存时传入了NULL值,导致数据库约束校验失败。
  2. 前端表单问题:message输入框未添加必填校验,用户可空提交;按钮的data toggle属性缺少连字符(应为data-toggle),可能导致弹窗交互异常。
  3. 视图层校验缺失:未对message是否为空做判断,直接存入数据库。
  4. 迁移异常残留:此前终止迁移可能导致数据库表结构与模型定义不一致,比如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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 08:57:34