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

Django CreateView提交评分时出现grader_id非空约束失败报错

问题根因

抛出NOT NULL constraint failed: auctions_grade.grader_id是因为Grade模型的grader外键设置了非空约束,但提交表单创建Grade记录时,没有给这个字段赋值,数据库写入时校验失败。
当前视图代码存在几个直接触发问题的错误:

  • 重写的get方法破坏了CreateView的内置逻辑,传入模板的是表单类而非实例化的表单对象,定义的user、grades、editable变量均未传入上下文,属于无效代码
  • 没有在表单保存前注入请求相关的自动赋值字段——grader(当前登录用户)、hw_upload(被评分的作业对象)这类不需要用户填写的非空外键,完全没有赋值逻辑
  • get_success_url方法存在缩进错误,会直接触发语法异常
  • 模板路径配置不一致,类属性里写的是grading.html,手动render时用的是auctions/grading.html
修复方案

1. 重构GradeView视图

直接删除冗余的get方法重写,利用CreateView内置的表单处理逻辑,通过重写form_valid方法给非用户填写字段赋值,同时加上登录校验避免匿名用户访问:

from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
from .models import Grade, Hw_upload
from .forms import Hw_gradeForm

class GradeView(LoginRequiredMixin, CreateView):
    model = Grade
    template_name = "auctions/grading.html"
    form_class = Hw_gradeForm

    def get_success_url(self):    
        return reverse_lazy('homework_upload', args=(self.object.hw_upload.id,))  

    def form_valid(self, form):
        # 暂不提交数据库,先给自动填充字段赋值
        grade = form.save(commit=False)
        # 绑定评分人为当前登录用户
        grade.grader = self.request.user
        # 从URL参数获取待评分的作业对象,绑定外键
        target_hw = Hw_upload.objects.get(pk=self.kwargs["hw_pk"])
        grade.hw_upload = target_hw
        # 自动从作业对象同步关联的课程、模块、活动字段,无需手动传参
        grade.course_grade = target_hw.course_hw_upload
        grade.module_grade = target_hw.module_hw_upload
        grade.activity_grade = target_hw.activity
        grade.graded = True
        # 写入数据库
        grade.save()
        return super().form_valid(form)

2. 调整路由配置

因为代码里从URL参数取hw_pk获取待评作业,需要在urls.py里对应配置参数:

from django.urls import path
from . import views

urlpatterns = [
    # 其余路由省略
    path("grade/<int:hw_pk>/", views.GradeView.as_view(), name="grade_homework"),
]

在作业详情页跳转评分入口时,传入对应作业ID即可:

<a href="{% url 'grade_homework' hw.pk %}" class="btn btn-primary">提交评分</a>

3. 可选权限校验

如果需要限制只有教授角色可以评分,可以再加UserPassesTestMixin做权限判断,避免学生账号访问评分接口:

from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin

class GradeView(LoginRequiredMixin, UserPassesTestMixin, CreateView):
    # 其余代码不变
    def test_func(self):
        # 只允许教授角色用户访问,根据你自己的用户角色字段调整判断逻辑即可
        return self.request.user.is_professor

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:36:20