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

成绩系统:实现依赖班级、学生下拉菜单的动态科目输入表单

成绩录入表单动态生成成绩输入框问题

我正在开发一套成绩系统,负责实现学生成绩录入表单。表单包含班级、学生两个关联下拉菜单,已完成“选择班级后仅显示对应班级学生”的功能。现在需要实现:选择学生后,根据该学生修读的科目数量,动态生成对应数量的成绩输入框,用于录入各科成绩。比如选择1b班的Mary后,若她修读5门科目,就显示5个成绩输入框。


现有模型代码(models.py)

# 班级模型
class Classroom(models.Model):
    name = models.CharField()  # 班级名称

# 成绩模型
class Marks(models.Model):
    classroom = models.ForeignKey(Classroom)  # 关联班级
    Grade = models.FloatField()  # 成绩

HTML表单代码

<div class="container-fluid">
    <form id="result-form" method="post">
        {% csrf_token %}
        <!-- 模态框 -->
        <div class="modal-header">
            <h5 class="modal-title" id="staticBackdropLabel"> {% block modal-title%} 添加成绩 {% endblock%}</h5>
            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="关闭"></button>
        </div>
        <div class="modal-body">
            <div class="row">
                <div class="col-md-12" id="msg8" style="font-size: 2rem; color:rgb(255, 144, 47)"></div>

                <div class="col-md-12 form-group p-2">
                    <label class="form-label">班级名称</label>
                    {% render_field form.room class+="form-control" %}
                </div>

                <div class="col-md-12 form-group p-2">
                    <label class="form-label">考试名称</label>
                    {% render_field form.exam class+="form-control" %}
                </div>

                <div class="col-md-12 form-group p-2">
                    <label class="form-label">学生</label>
                    {% render_field form.student class+="form-control select2" %}
                </div>
                <!-- 动态生成的成绩输入框容器 -->
                <div class="hidden" id="subject-fields"></div>

                <div class="form-group mb-3 pt-2">
                    <button type="button" id="resBtn" class="btn btn-info" title="添加">提交</button>
                </div>
            </div>
        </div>
    </form>
</div>

{% block script%}
{% endblock%}

现有JavaScript脚本

$(document).on('click', '#submit-btn', function(event){
    var response_data = []
    var subject_name= $('.course');
    var subject_objs = $('.subject_id');

    for(i=0;i<subject_name.length;i++){
        var subject_id = $(subject_objs[i]).find('input').val();
        var grade_input = {
            "Marks": subject_id,
        }
        response_data.push(grade_input);
    }
    $.ajax({
        type: "POST",
        url: "{% url 'marks' %}",
        data: response_data,
        success: function(response){
            alert("提交成功");
        }
    });
});

视图参考示例

def question_choice_view(request):
    if request.method == "POST":
        question_choice_data = request.POST['data']

实现方案

  1. 后端新增接口:编写一个AJAX接口,接收学生ID,返回该学生修读的科目列表(包含科目ID、名称)
from django.http import JsonResponse
from .models import StudentSubject  # 假设存在学生-科目关联模型

def get_student_subjects(request):
    student_id = request.GET.get('student_id')
    subjects = StudentSubject.objects.filter(student_id=student_id).values('id', 'name')
    return JsonResponse({'subjects': list(subjects)})
  1. 前端绑定学生选择事件:监听学生下拉框的change事件,请求接口获取科目并生成输入框
// 绑定学生选择事件
$('#id_student').on('change', function() {
    var studentId = $(this).val();
    var container = $('#subject-fields');
    
    if (studentId) {
        $.ajax({
            url: "{% url 'get_student_subjects' %}",
            data: { 'student_id': studentId },
            success: function(data) {
                container.empty().removeClass('hidden');
                // 循环生成科目成绩输入框
                $.each(data.subjects, function(index, subject) {
                    var fieldHtml = `
                        <div class="col-md-12 form-group p-2">
                            <label class="form-label">${subject.name}</label>
                            <input type="hidden" name="subject_ids[]" value="${subject.id}">
                            <input type="number" name="grades[]" class="form-control" placeholder="输入成绩" min="0" max="100">
                        </div>
                    `;
                    container.append(fieldHtml);
                });
            }
        });
    } else {
        // 未选择学生时清空并隐藏容器
        container.empty().addClass('hidden');
    }
});
  1. 修改提交逻辑:收集所有科目对应的成绩数据,统一提交到后端
$(document).on('click', '#resBtn', function(event){
    var response_data = {
        'student_id': $('#id_student').val(),
        'exam_id': $('#id_exam').val(),
        'subjects': []
    };
    
    // 收集科目和成绩
    $('input[name="subject_ids[]"]').each(function(index) {
        var subjectId = $(this).val();
        var grade = $('input[name="grades[]"]').eq(index).val();
        response_data.subjects.push({
            'subject_id': subjectId,
            'grade': grade
        });
    });
    
    $.ajax({
        type: "POST",
        url: "{% url 'marks' %}",
        data: JSON.stringify(response_data),
        contentType: "application/json",
        success: function(response){
            alert("成绩录入成功");
            $('#result-form')[0].reset();
            $('#subject-fields').empty().addClass('hidden');
        }
    });
});
  1. 后端处理提交数据:接收并保存成绩
def save_marks(request):
    if request.method == "POST":
        data = json.loads(request.body)
        student_id = data['student_id']
        exam_id = data['exam_id']
        
        for item in data['subjects']:
            Marks.objects.create(
                student_id=student_id,
                exam_id=exam_id,
                subject_id=item['subject_id'],
                Grade=float(item['grade'])
            )
        return JsonResponse({'status': 'success'})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 20:09:23