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

毕业设计:学校管理系统评分模块预填与更新问题求助

学校管理系统成绩模块问题及解决方案

问题描述

我正在开发毕业设计项目——学校管理系统,在实现成绩模块时卡壳3周,目前功能接近预期:可根据选定科目在页面列出所有学生,教师能在学生姓名旁输入成绩。但存在两个核心问题:

  • 输入框未预填数据库中已有的学生成绩
  • 针对同一学生、同一科目、同一季度及学年输入成绩时,系统会创建新的成绩对象而非更新已有记录

效果对比

当前输出:
当前输出
预期输出:
预期输出

现有代码

视图代码

def add_gradebook_for(request, id):
    global student, s
    current_year = AcademicYear.objects.get(active=True)
    current_quarter = Quarter.objects.get(active=True)
    if request.method == 'GET':
        subjects = Subject.objects.filter(faculty_id=request.user.id)
        subject = Subject.objects.get(pk=id)
        students = Students.objects.filter(section__subject_section__in=[subject])
        context = {
            "subjects": subjects,
            "subject": subject,
            "students": students,
        }
        return render(request, 'grading/add_gradebook_for.html', context)

    if request.method == 'POST':
        ids = ()
        data = request.POST.copy()
        data.pop('csrfmiddlewaretoken', None)
        subject = Subject.objects.get(pk=id)
        for key in data.keys():
            ids = ids + (str(key),)
        for s in range(0, len(ids)):
            student = Students.objects.get(id=ids[s])
            score = data.getlist(ids[s])
            total_grade = score[0]
            obj = Students.objects.get(id=ids[s])
            obj.total_grade = total_grade
            try:
                a = Gradebook.objects.get(student=student, subject=subject, total_grade=total_grade, academic_year=current_year, quarter=current_quarter)
                a.total_grade = total_grade
                a.subject = subject
                a.save()
            except:
                Gradebook.objects.update_or_create(student=student, subject=subject, total_grade=total_grade, academic_year=current_year, quarter=current_quarter)
        messages.success(request, "Grades Successfully Recorded!")
        return HttpResponseRedirect(reverse_lazy('add_gradebook_for', kwargs={'id': id}))

HTML模板(省略无关部分)

<div class="card-body">
        <div id="table" class="table-editable">

          <table class="table table-bordered table-responsive-md table-striped text-center">
            <tr>
              <th class="text-center">Student</th>
              <th class="text-center">Grade</th>
            </tr>
            {% for student in students %}
            <tr>
              <td class="pt-3-half" name="{{ student.id }}">
                    {{ student.first_Name }} {{ student.last_Name }}
              </td>
              <td class="pt-3-half">
                <input id="total_grade" class="score" type="number" name="{{ student.id }}" value="{{ student.total_grade }}">
              </td>
            </tr>
            {% endfor %}
          </table>
        </div>
      </div>

模型(省略无关字段)

class Gradebook(models.Model):
    subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
    student = models.ForeignKey(Students, on_delete=models.CASCADE)
    total_grade = models.FloatField(blank=True, null=True, default=0, max_length=5)
    academic_year = models.ForeignKey(AcademicYear, on_delete=models.CASCADE)
    quarter = models.ForeignKey(Quarter, on_delete=models.CASCADE)

class Subject(models.Model):
    section = models.ForeignKey(Section, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    faculty = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE)

class Section(models.Model):
    level = models.ForeignKey(Level, null=True, on_delete=models.CASCADE)
    section = models.CharField(max_length=15)

class Students(models.Model):
    name = models.CharField(max_length=50)
    section = models.ForeignKey(Section, on_delete=models.CASCADE)

问题解决

1. 输入框预填已有成绩

问题根源

模板中调用student.total_grade,但Students模型并未定义该字段,实际成绩存储在Gradebook模型中,关联条件为学生、科目、当前学年和季度。

修复步骤

  • 修改视图GET逻辑:为每个学生查询对应科目的当前成绩,存入字典传递到模板
if request.method == 'GET':
    subjects = Subject.objects.filter(faculty_id=request.user.id)
    subject = Subject.objects.get(pk=id)
    students = Students.objects.filter(section__subject_section__in=[subject])
    # 构建学生ID到成绩的映射
    student_grades = {}
    for student in students:
        try:
            grade_record = Gradebook.objects.get(
                student=student,
                subject=subject,
                academic_year=current_year,
                quarter=current_quarter
            )
            student_grades[student.id] = grade_record.total_grade
        except Gradebook.DoesNotExist:
            student_grades[student.id] = 0  # 无成绩时显示默认值0
    context = {
        "subjects": subjects,
        "subject": subject,
        "students": students,
        "student_grades": student_grades,
    }
    return render(request, 'grading/add_gradebook_for.html', context)
  • 添加模板过滤器:在app目录下创建templatetags/grade_filters.py,实现字典取值过滤器
from django import template

register = template.Library()

@register.filter
def get_item(dictionary, key):
    return dictionary.get(key, 0)
  • 修改模板:加载过滤器并更新输入框的value值
{% load grade_filters %}

<!-- 省略其他代码 -->
<input id="total_grade" class="score" type="number" name="{{ student.id }}" value="{{ student_grades|get_item:student.id }}">

2. 避免重复创建成绩对象

问题根源

update_or_create的查询参数包含total_grade,导致成绩变化时系统判定为新对象;同时try块中查询已有记录也错误地将total_grade作为条件,无法匹配到原有记录。

修复步骤

  • 简化并修正POST逻辑:以学生、科目、学年、季度为唯一标识,使用update_or_create直接更新或创建记录,删除无用的Students对象操作
if request.method == 'POST':
    data = request.POST.copy()
    data.pop('csrfmiddlewaretoken', None)
    subject = Subject.objects.get(pk=id)
    # 遍历所有提交的学生成绩
    for student_id, score in data.items():
        student = Students.objects.get(id=student_id)
        total_grade = float(score)
        # 按唯一条件更新或创建成绩记录
        Gradebook.objects.update_or_create(
            student=student,
            subject=subject,
            academic_year=current_year,
            quarter=current_quarter,
            defaults={'total_grade': total_grade}
        )
    messages.success(request, "成绩已成功记录!")
    return HttpResponseRedirect(reverse_lazy('add_gradebook_for', kwargs={'id': id}))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 00:01:09