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

Django关联选择功能开发遇阻:选校后筛课添加学生报错

问题分析与解决方案

你遇到的AttributeError: 'SelectCourseForm' object has no attribute 'get'错误,核心原因是表单初始化时的父类构造调用错误,同时存在几处代码细节问题,以下是分步修正方案:

1. 修复SelectCourseForm的初始化方法

你的SelectCourseForm在调用父类构造时错误传入了self参数,这会破坏表单内部的核心方法逻辑。

错误代码:

def __init__(self, school, *args, **kwargs):
    super().__init__(self, *args, **kwargs)  # 错误:多传了self参数
    self.fields['course'].queryset = Courses.objects.filter(school_id=school)

修正后:

class SelectCourseForm(forms.ModelForm):
    def __init__(self, school_id, *args, **kwargs):
        super().__init__(*args, **kwargs)  # 移除多余的self参数
        # 过滤当前学校下的课程
        self.fields['course'].queryset = Courses.objects.filter(school_id=school_id)
    
    class Meta:
        model = Student
        fields = ('student_id', 'course')
        labels = {'student_id':'', 'course':''}
        widgets = {
            'student_id': forms.widgets.TextInput(attrs={"placeholder":"Student ID", "class":"form-control"}),
            'course': forms.widgets.Select(attrs={"placeholder":"Course", "class":"form-select"}),
        }

2. 修正视图中表单的实例化逻辑

在course_selection视图里,需区分GET/POST请求的表单实例化方式,同时确保参数顺序正确:

错误代码:

form = SelectCourseForm(school_id, request.POST or None)

修正后:

def course_selection(request, school_id):
    if request.method == "POST":
        form = SelectCourseForm(school_id, request.POST)
        if form.is_valid():
            form.save()
            messages.success(request, "Record added successfully!")
            return redirect('school')
    else:
        # GET请求生成空表单
        form = SelectCourseForm(school_id)
    context = {'form':form}
    return render(request, 'course_selection.html', context)

3. 修复模型中的细节问题

  • Student类Meta缩进错误:原代码中class Meta未缩进在Student类内部,导致排序和索引规则不生效:
class Student(models.Model):
    course = models.ForeignKey(Courses,  on_delete=models.PROTECT)
    created_at = models.DateTimeField(auto_now_add=True)
    student_id = models.CharField(max_length=20, null=True, blank=True)

    # 修正缩进:Meta需作为Student的内部类
    class Meta:
        ordering = ['course']
        indexes = [models.Index(fields=['course'])]
  • Courses的related_name命名优化:原related_name='school'易混淆,建议改为'courses',方便通过School实例反向查询课程:
school = models.ForeignKey(School, on_delete=models.PROTECT, related_name='courses')

4. 优化SelectSchoolForm的模型关联

原SelectSchoolForm绑定Courses模型会导致学校选项重复,直接关联School模型更合理:

class SelectSchoolForm(forms.ModelForm):
    class Meta:
        model = School
        fields = ('id',)
        labels = {'id':'School', }
        widgets = {'id': forms.Select(attrs={"placeholder":"School", "class":"form-select"})}
    
    # 自定义下拉选项显示为学校ID+名称
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['id'].label_from_instance = lambda obj: f"{obj.id} {obj.school_name}"

验证修正效果

完成以上修改后:

  1. 用户在choose_school7页面选择学校,提交后跳转到对应学校的课程选择页面
  2. 课程选择页面的下拉框仅显示当前学校的课程
  3. 填写学生ID并选择课程后提交,会成功创建Student记录

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 13:23:12