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
相关产品推荐
相关产品推荐

