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

Django非空约束异常:保存表单时触发NOT NULL约束失败

问题分析与解决

核心错误原因

IntegrityError: NOT NULL constraint failed: lessons_request.student_id 是因为表单的自定义save方法未生效,导致保存Request模型时student字段未被赋值,违反了该字段的非空约束。

具体问题出在forms.py中:自定义的save方法被错误缩进在了Meta类内部,属于Meta的方法而非RequestLessonsForm的方法,因此调用form.save(user)时,实际执行的是ModelForm默认的save方法,该方法不会自动设置student字段。

修正步骤

1. 修复forms.py中save方法的缩进

将save方法移到Meta类外部,作为RequestLessonsForm的直接方法,同时优化实现逻辑:

class RequestLessonsForm(forms.ModelForm):
    class Meta:
        model = Request
        fields = ['availability', 'num_of_lessons', 'interval_between_lessons', 'duration_of_lesson','further_information']
        widgets = {'further_information' : forms.Textarea()}

    # 正确缩进:属于RequestLessonsForm的方法
    def save(self, user):
        # 获取未提交到数据库的模型实例
        instance = super().save(commit=False)
        # 为实例设置student字段
        instance.student = user
        # 保存到数据库
        instance.save()
        return instance

2. 修正views.py中的逻辑运算符

将位运算符&替换为逻辑运算符and,符合Python逻辑判断的规范:

def requestLessons_view(request):
    if request.method == 'POST':
        form = RequestLessonsForm(request.POST)
        # 用and代替&,逻辑判断更清晰规范
        if form.is_valid() and request.user.is_authenticated:
            user = request.user
            form.save(user)
            return redirect('login')
    else:
        form = RequestLessonsForm()
    return render(request, 'RequestLessonsPage.html', {'form': form})

额外说明

原save方法中使用Request.objects.create的方式本身可行,但前提是方法要在正确的位置。使用super().save(commit=False)的方式更符合Django ModelForm的设计模式,无需重复从cleaned_data中提取字段值,代码更简洁易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 06:01:07