Django框架【五】—教学管理模块代码实现
一、教学模块实现
1.班级课程记录展示
客户成功转化后,就成为我们教学机构的学生,既然是我们学生,那么他是报名的什么课程啊,还有报名的具体是哪一期啊?
学校根据学生报名课程来划分班级,而我们的班级记录表就是用来记录某个班级某一天课程的详细信息,比如课程节次,课程内容,课程作业内容等等。
学生学习记录表就是用来记录某个班级的每一位学生在某一天的课程学习信息,比如他的考勤,作业提交情况,老师对作业的批语等等。
对应的数据表结构之前已详细介绍,不再赘述。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from django.db import models # Create your models here. # 课程选择 course_choices = ( ('Linux', 'Linux高级'), ('PythonFullStack', 'Python高级全栈开发'), ('BigData', '大数据开发'), ) # 班级类型 class_type_choices = (('fulltime', '脱产班',), ('online', '网络班'), ('weekend', '周末班',),) # 分数分类 score_choices = ((100, 'A+'), (90, 'A'), (85, 'B+'), (80, 'B'), (70, 'B-'), (60, 'C+'), (50, 'C'), (40, 'C-'), (0, ' D'), (-1, 'N/A'), (-100, 'COPY'), (-1000, 'FAIL'),) # 记录选项 record_choices = ( ('checked', "已签到"), ('vacate', "请假"), ('late', "迟到"), ('absence', "缺勤"), ('leave_early', "早退"), ) # 校区表 class Campuses(models.Model): """ 校区表 """ name = models.CharField(verbose_name='校区', max_length=64) address = models.CharField(verbose_name='详细地址', max_length=512, blank=True, null=True) def __str__(self): return self.name # 班级表 class ClassList(models.Model): """ 班级表 """ course = models.CharField("课程名称", max_length=64, choices=course_choices) semester = models.IntegerField("学期") # python20期等 campuses = models.ForeignKey('Campuses', verbose_name="校区", on_delete=models.CASCADE) price = models.IntegerField("学费", default=10000) memo = models.CharField('说明', blank=True, null=True, max_length=100) start_date = models.DateField("开班日期") graduate_date = models.DateField("结业日期", blank=True, null=True) # 不一定什么时候结业,哈哈,所以可为空 # contract = models.ForeignKey('ContractTemplate', verbose_name="选择合同模版", blank=True, null=True,on_delete=models.CASCADE) teachers = models.ManyToManyField('rbac.UserInfo', verbose_name="老师") # 对了,还有一点,如果你用的django2版本的,那么外键字段都需要自行写上on_delete=models.CASCADE class_type = models.CharField(choices=class_type_choices, max_length=64, verbose_name='班额及类型', blank=True, null=True) class Meta: unique_together = ("course", "semester", 'campuses') def __str__(self): return "{}{}({})".format(self.get_course_display(), self.semester, self.campuses) class Student(models.Model): """ 学生表(已报名) """ customer = models.OneToOneField(verbose_name='客户信息', to='customer.Customer', on_delete=models.CASCADE, null=True,blank=True) class_list = models.ManyToManyField(verbose_name="已报班级", to='ClassList', blank=True, related_name="students") emergency_contract = models.CharField(max_length=32, blank=True, null=True, verbose_name='紧急联系人') # 学员毕业就业后的相关信息字段,默认为空 company = models.CharField(verbose_name='公司', max_length=128, blank=True, null=True) date = models.DateField(verbose_name='入职时间', help_text='格式yyyy-mm-dd', blank=True, null=True) location = models.CharField(max_length=64, verbose_name='所在区域', blank=True, null=True) position = models.CharField(verbose_name='岗位', max_length=64, blank=True, null=True) salary = models.IntegerField(verbose_name='薪资', blank=True, null=True) welfare = models.CharField(verbose_name='福利', max_length=256, blank=True, null=True) memo = models.CharField(verbose_name='备注', max_length=256, blank=True, null=True) def __str__(self): return self.customer.name class ClassStudyRecord(models.Model): """ 上课记录表 (班级记录) """ class_obj = models.ForeignKey(verbose_name="班级", to="ClassList", on_delete=models.CASCADE) day_num = models.IntegerField(verbose_name="节次", help_text=u"此处填写第几节课或第几天课程...,必须为数字") teacher = models.ForeignKey(verbose_name="讲师", to='rbac.UserInfo', on_delete=models.CASCADE) date = models.DateField(verbose_name="上课日期") course_title = models.CharField(verbose_name='本节课程标题', max_length=64, blank=True, null=True) course_memo = models.TextField(verbose_name='本节课程内容概要', blank=True, null=True) has_homework = models.BooleanField(default=False, verbose_name="本节有作业", blank=True) homework_title = models.CharField(verbose_name='本节作业标题', max_length=64, blank=True, null=True) homework_memo = models.TextField(verbose_name='作业描述', max_length=500, blank=True, null=True) exam = models.TextField(verbose_name='得分点', max_length=300, blank=True, null=True) def __str__(self): return "{0} day{1}".format(self.class_obj, self.day_num) class StudentStudyRecord(models.Model): ''' 学生学习记录 ''' student = models.ForeignKey(verbose_name="学员", to='Student', on_delete=models.CASCADE) class_study_record = models.ForeignKey(verbose_name="第几天课程", to="ClassStudyRecord", on_delete=models.CASCADE) record = models.CharField("上课纪录", choices=record_choices, default="checked", max_length=64) score = models.IntegerField("本节成绩", choices=score_choices, default=-1) homework = models.FileField(verbose_name='作业文件', blank=True, null=True, default=None) stu_memo = models.TextField(verbose_name='学员备注', blank=True, null=True) date = models.DateTimeField(verbose_name='提交作业日期', auto_now_add=True) homework_note = models.CharField(verbose_name='作业评语', max_length=255, blank=True, null=True) note = models.CharField(verbose_name="备注", max_length=255, blank=True, null=True) def __str__(self): return "{0}-{1}".format(self.class_study_record, self.student) class Meta: unique_together = ["student", "class_study_record"]
在实现需求之前我们模拟一些数据量,数据内容大致如下:
班级课程url
项目下的url分发
url(r'^education/', include("education.urls")),
education下的url写法
from education.views import education from django.conf.urls import url urlpatterns = [ # 班级课程记录展示 url(r'^class/record/list/', education.ClassStudyRecord.as_view(), name="class_record"), ]
班级课程视图
班级信息展示url,展示课程的详细记录,在班级课程展示的页面中,有两个功能要实现:
- 对某个班级的学生进行批量创建学习记录。
- 通过点击班级详情可以批量修改该班级的所有学生的学习记录。
# 班级学习记录视图 class ClassStudyRecord(views.View): @method_decorator(login_required) # 校验用户登录 def dispatch(self, request, *args, **kwargs): res = super().dispatch(request,*args,**kwargs) return res def get(self,request): # 获取所有班级的课程记录 all_records = models.ClassStudyRecord.objects.all() return render(request, "class_record_list.html", {"all_records":all_records}) def post(self,request): # 获取批量操作类型 operate = request.POST.get("operate") # 获取批量提交的班级课程记录id selected_id = request.POST.getlist("choose") print(operate) if hasattr(self,operate): # 反射类中的批量操作方法 getattr(self,operate)(selected_id) return self.get(request) def batch_create(self,selected_id): for class_record_id in selected_id: # 根据班级课程记录查到多有的学生对象. # 注意班级和学生,一对多关联,通过班级反向找学生,类名小写_set.all(),但是外键字段取了related_name,所以直接使用别名students.all() all_students = models.ClassStudyRecord.objects.get(pk=class_record_id).class_obj.students.all() # print(all_students) # 给所有学生创建一条学习记录,只填好学生姓名,和所属的哪一节课程. li = [] for student in all_students: # 根据每一个学生实例化一个学生学习记录对象 student_record = models.StudentStudyRecord( student=student, class_study_record_id=class_record_id ) li.append(student_record) # 批量创建记录 models.StudentStudyRecord.objects.bulk_create(li)
前端页面html写法
批量创建通过select和input的checkbox来提交批量创建的类型和需要批量创建的记录对象。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{% extends 'BASE.html' %} {% load static %} {% block head %} {{ block.super }} {% endblock head %} {% block title %} 班级学习记录表 {% endblock title %} {% block content %} <div class="row"> <div class="col-xs-12"> <div class="box"> <div class="box-header"> <h3 class="box-title"></h3> <form action="" method="get" class="navbar-form navbar-left"> <div class="input-group"> <div class="input-group-btn btn-info"> <select name="condition" id="search" class="btn input-group-sm btn-info" style="border: 0"> </select> </div> <input type="text" name="q" class="form-control" placeholder="Search..."> <span class="input-group-btn"> <button type="submit" id="search-btn" class="btn btn-flat"> <i class="fa fa-search"></i> </button> </span> </div> </form> <a href="" class="btn btn-primary pull-right">新增记录</a> </div> <div class="box-body"> <div class="row"> <div class="col-sm-6"> </div> </div> <form action="" method="post"> {% csrf_token %} <div class="input-group" style="width: 220px;margin-bottom: 5px;margin-left: 15px"> <select name="operate" id="operate" class="form-control btn-default"> <option value="batch_create">批量添加学生学习记录</option> </select> <span class="input-group-btn"> <button type="submit" class="btn btn-warning btn-flat">Go!</button> </span> </div> <table id="example2" class="table table-bordered table-hover text-center"> <thead> <tr> <th style="width: 8%"> <button type="button" class="btn btn-info btn-xs"><input type="checkbox" name="batch_choose"></button> </th> <th style="width: 5%">序号</th> <th>班级</th> <th>节次</th> <th>老师</th> <th>课程标题</th> <th>学习详情</th> <th>操作</th> </tr> </thead> <tbody> {% for record in all_records %} <tr> <td><input type="checkbox" name="choose" value="{{ record.pk }}"></td> <td>{{ forloop.counter }}</td> <td>{{ record.class_obj }}</td> <td>{{ record.day_num }}</td> <td>{{ record.teacher }}</td> <td>{{ record.course_title|default:"暂无" }}</td> <td><a href="{% url 'student_record' record.pk %}">查看</a></td> <td> <a style="color: #00c3cc;" href=""> <i class="fa fa-edit" aria-hidden="true"></i> </a> | <a style="color: #d9534f;" href="" > <i class="fa fa-trash-o"></i> </a> </td> </tr> {% endfor %} </tbody> <tfoot> </tfoot> </table> {% if not all_records %} <h3 class="text-center">没有相关记录!</h3> {% endif %} <div class="pull-right" style="display:inline-block; width: 120px;margin: 22px 10px"> {{ jump_tag|safe }} </div> <div class="pull-right"> {{ paginator_tag|safe }} </div> </form> </div> <!-- /.box-body --> </div> <!-- /.box --> </div> <!-- /.col --> </div> {% endblock content %} {% block js %} {{ block.super }} {% endblock js %} {% block customjs %} <script> $("[name=batch_choose]").click(function () { var status = $(this).prop("checked"); $("[name=choose]").prop('checked', status) }); </script> {% endblock customjs %}
班级课程记录页面效果
2.学生学习记录展示和批量修改
我们在班级课程展示页面中实现了一个详情连接,点击详情可以批量修改这个班级所有学生的记录。
然后学生学习记录信息也有一个展示页面,这里学生学习信息页面展示视图和批量编辑视图我们通过一个视图来实现,get处理页面展示,post处理批量修改的数据保存。
urls.py文件
# 学员学习记录展示 url(r'^student/record/list/(\d+)?/?', education.StudentStudyRecord.as_view(), name="student_record"),
视图文件的写法
学生学习记录的批量修改,可以通过两种方式实现。
- 获取某个班级的所有学生学习记录,并且获取学生中字段的选项数据,生成下拉框,或者输入框,用来获取提交的批量数据。
- 通过modelformset组件,自动生成批量修改的前端页面。
这里我们详细介绍一下modelformset方法的使用:生成批量修改页面,并能根据提交的数据批量保存到数据库。
为什么使用modelformset?
我们知道modelform可以生成单条记录的修改页面,但是无法解决多条记录的批量修改页面。所以modelform对于这种场景无法适用。
而modelformset可以根据你传递的多条记录,根据这些记录对象生成批量修改的页面,并且批量保存到数据库。
具体使用方法:
使用modelfromset需要导入一个django的内置模块
from django.forms.models import modelformset_factory
既然是modelformset,那么也当然少不了modelform,我们在education应用下froms文件夹下新建formauth.py,写入我们需要的modelform
from django import forms from student import models class StudentStudyRecordMF(forms.ModelForm): class Meta: model = models.StudentStudyRecord # 指定一个表 # fields = '__all__' fields = ['score','homework_note'] # 只验证两个字段,其他字段放行
在视图中使用
# 第二种方式,通过使用modelformset来生成批量修改的页面 def batch_edit_mfs(self,request,class_record_id): # 通过班级记录id,找到班级课程的那一条记录 class_record_obj = models.ClassStudyRecord.objects.get(pk=class_record_id) # 通过班级对象,找到这节班级课程的所有学生学习记录 all_records = models.StudentStudyRecord.objects.filter( class_study_record=class_record_obj, ) # 实例化一个form_set对象 form_set_obj = modelformset_factory( model=models.StudentStudyRecord, # 指定一张表 form=StudentStudyRecordMF, # 指定一个modelform extra=0 # 可以指定生成表中,新建数据的行数,看页面效果就理解了 ) # 将所有的学生学习记录传给form_set对象的queryset all_records = form_set_obj(queryset=all_records) return render(request,"student_record_edit.html",{"class_record_obj":class_record_obj,"all_records":all_records})
前端页面中的使用modelformset
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<form action="" method="post"> {% csrf_token %} <div class="input-group" style="width: 220px;margin-bottom: 5px;margin-left: 15px"> <select name="operate" id="operate" class="form-control btn-default"> </select> <span class="input-group-btn"> <button type="submit" class="btn btn-warning btn-flat">Go!</button> </span> </div> <table id="example2" class="table table-bordered table-hover text-center"> {{ all_records.management_form }} <!-- 这句话一定要加上,固定的昂 不然会报错['ManagementForm data is missing or has been tampered with'] --> <thead> <tr> <th>姓名</th> <th>考勤</th> <th>作业成绩</th> <th>作业评语</th> </tr> </thead> <tbody> {% for record in all_records %} <tr> {{ record.id }} <td>{{ record.instance.student }}</td> <td>{{ record.instance.get_record_display }}</td> <td>{{ record.score }}</td> <td>{{ record.homework_note }}</td> </tr> {% endfor %} </tbody> </table> <input type="submit" class="btn btn-success pull-right" value="批量提交"> {% if not all_records %} <h3 class="text-center">没有相关记录!</h3> {% endif %} <div class="pull-right" style="display:inline-block; width: 120px;margin: 22px 10px"> {{ jump_tag|safe }} </div> <div class="pull-right"> {{ paginator_tag|safe }} </div> </form>
学生学习记录的视图
虽然我们只着重说了modelformset的使用,但是在视图函数处理中,我把普通方式(自己手动遍历数据,写标签展示)和modelformset自动生成的方式都写了。有兴趣可以详细查看。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 学生学习记录视图,普通的 class StudentStudyRecord(views.View): @method_decorator(login_required) def dispatch(self, request, *args, **kwargs): ret = super().dispatch(request,*args,**kwargs) return ret def get(self,request,class_record_id=None): if class_record_id: # 有班级id,说明是批量修改请求 # 通过modelformset批量修改 ret = self.batch_edit_mfs(request,class_record_id) else: # 没有是数据展示请求 ret = self.display(request) return ret def display(self,request): """ 直接请求学生学习记录展示的页面 :param request: :return: """ # 找到这节班级课程的所有学生学习记录 all_records = models.StudentStudyRecord.objects.all() # 获取分数的可选选项 score_choices = models.score_choices return render(request, "student_study_record_list.html",{"all_records": all_records,"score_choices": score_choices}) """批量修改展示数据的两种方式""" # 第一种方式,通过手动遍历数据展示批量修改的数据列表 def batch_edit(self,request,class_record_id): # 通过班级记录id,找到班级课程的那一条记录 class_record_obj = models.ClassStudyRecord.objects.get(pk=class_record_id) # 通过班级对象,找到这节班级课程的所有学生学习记录 all_records = models.StudentStudyRecord.objects.filter(class_study_record=class_record_obj) # 获取分数的可选选项 score_choices = models.score_choices return render(request,"student_study_record_edit.html",{"class_record_obj":class_record_obj,"all_records":all_records,"score_choices":score_choices}) # 第二种方式,通过使用modelformset来生成批量修改的页面 def batch_edit_mfs(self,request,class_record_id): # 通过班级记录id,找到班级课程的那一条记录 class_record_obj = models.ClassStudyRecord.objects.get(pk=class_record_id) # 通过班级对象,找到这节班级课程的所有学生学习记录 all_records = models.StudentStudyRecord.objects.filter( class_study_record=class_record_obj, ) # 实例化一个form_set对象 form_set_obj = modelformset_factory( model=models.StudentStudyRecord, # 指定一张表 form=StudentStudyRecordMF, # 指定一个modelform extra=0 # 可以指定生成表中,新建数据的行数,看页面效果就理解了 ) # 将所有的学生学习记录传给form_set对象的queryset all_records = form_set_obj(queryset=all_records) return render(request,"student_study_record_edit.html",{"class_record_obj":class_record_obj,"all_records":all_records}) """批量提交修改数据的两种方式""" def post(self,request,class_record_id=None): # 调用不同的方式来批量修改数据 self.batch_commit_mfs(request,class_record_id) return self.get(request,class_record_id) # 第一种方式,通过手动获取数据,提取数据结构来更新数据 def batch_commit(self,request,class_record_id): data = request.POST # print(data) # <QueryDict: {'csrfmiddlewaretoken': ['R73Lgac0jPy6YwP1guZ4fC5wLsrVY4iGgd45hip6xtcxZNfuiysmRwGt2IZhi0K0'], 'socre_1': ['80'], 'homework_note_1': ['请问'], 'socre_4': ['90'], 'homework_note_4': ['武器二人'], 'socre_5': ['100'], 'homework_note_5': ['未确认']}> # 构件我们想要的数据类型 """ { 1:{"score":80,"homework_note":"123"}, 2:{"score":85,"homework_note":"456"}, } """ cleaned_data = {} for key,val in data.items(): if key == "csrfmiddlewaretoken":continue field,pk = key.rsplit("_",1) if pk in cleaned_data: cleaned_data[pk].update({field:val}) else: cleaned_data[pk] = {field:val} for pk,val in cleaned_data.items(): models.StudentStudyRecord.objects.filter(pk=pk).update(**val) # 第二种方式,通过modelformset提供的save方法存储 def batch_commit_mfs(self,request,class_record_id): # 通过班级记录id,找到班级课程的那一条记录 class_record_obj = models.ClassStudyRecord.objects.get(pk=class_record_id) # 实例化一个form_set对象 form_set_obj = modelformset_factory( model=models.StudentStudyRecord, # 指定一张表 form=StudentStudyRecordMF, # 指定一个modelform extra=0 # 可以指定生成表中,新建数据的行数,看页面效果就理解了 ) print(request.POST) # 将提交的form数据传给form_set对象 all_records = form_set_obj(request.POST) print(all_records) if all_records.is_valid(): # 对提交的数据进行验证 all_records.save() # 如果合法,则保存导数据 else: # 如果不合法,将错误的提示重新渲染到页面, print(all_records.errors)
前端html文件
前端页面也有两个,当我们想直接访问所有学生的学习记录时,我们直接请求这个url,而并没有传递班级记录id,这个时候是返回页面展示的html。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{% extends 'BASE.html' %} {% load static %} {% block head %} {{ block.super }} {% endblock head %} {% block title %} 学员学习记录 {% endblock title %} {% block content %} <div class="row"> <div class="col-xs-12"> <div class="box"> <div class="box-header"> <h3 class="text-center"></h3> <form action="" method="get" class="navbar-form navbar-left"> <div class="input-group"> <div class="input-group-btn btn-info"> <select name="condition" id="search" class="btn input-group-sm btn-info" style="border: 0"> </select> </div> <input type="text" name="q" class="form-control" placeholder="Search..."> <span class="input-group-btn"> <button type="submit" id="search-btn" class="btn btn-flat"> <i class="fa fa-search"></i> </button> </span> </div> </form> </div> <div class="box-body"> <div class="row"> <div class="col-sm-6"> </div> </div> <form action="" method="post"> {% csrf_token %} <div class="input-group" style="width: 220px;margin-bottom: 5px;margin-left: 15px"> <select name="operate" id="operate" class="form-control btn-default"> </select> <span class="input-group-btn"> <button type="submit" class="btn btn-warning btn-flat">Go!</button> </span> </div> <table id="example2" class="table table-bordered table-hover text-center"> <!--==========================第一种方式,手动生成批量修改表============================--> <thead> <tr> <th style="width: 8%"> <button type="button" class="btn btn-info btn-xs"><span>批量</span><input type="checkbox" name="batch_choose"></button> </th> <th style="width: 5%">序号</th> <th>学员</th> <th>考勤</th> <th>成绩</th> <th>批语</th> <th>操作</th> </tr> </thead> <tbody> {% for record in all_records %} <tr> <td><input type="checkbox" name="choose" value="{{ record.pk }}"></td> <td>{{ forloop.counter }}</td> <td>{{ record.student }}</td> <td>{{ record.get_record_display }}</td> <td>{{ record.score }}</td> <td> {{ record.homework_note|default:"暂无" }} </td> <td> <a style="color: #00c3cc;" href=""> <i class="fa fa-edit" aria-hidden="true"></i> </a> | <a style="color: #d9534f;" href="" > <i class="fa fa-trash-o"></i> </a> </td> </tr> {% endfor %} </tbody> <tfoot> </tfoot> </table> {% if not all_records %} <h3 class="text-center">没有相关记录!</h3> {% endif %} <div class="pull-right" style="display:inline-block; width: 120px;margin: 22px 10px"> {{ jump_tag|safe }} </div> <div class="pull-right"> {{ paginator_tag|safe }} </div> </form> </div> <!-- /.box-body --> </div> <!-- /.box --> </div> <!-- /.col --> </div> {% endblock content %} {% block js %} {{ block.super }} {% endblock js %} {% block customjs %} <script> $("[name=batch_choose]").click(function () { var status = $(this).prop("checked"); $("[name=choose]").prop('checked', status) }); </script> {{ jump_js|safe }} {% endblock customjs %}
当我们想批量修改某班级课程的所有学生对象,我们给后端传递了一个班级课程id,这个时候需要返回的是批量修改页面。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{% extends 'BASE.html' %} {% load static %} {% block head %} {{ block.super }} {% endblock head %} {% block title %} 学员学习记录 {% endblock title %} {% block content %} <div class="row"> <div class="col-xs-12"> <div class="box"> <div class="box-header"> <h3 class="text-center">{{ class_record_obj.class_obj }}-day{{ class_record_obj.day_num }}天-成绩录入</h3> <form action="" method="get" class="navbar-form navbar-left"> <div class="input-group"> <div class="input-group-btn btn-info"> <select name="condition" id="search" class="btn input-group-sm btn-info" style="border: 0"> </select> </div> <input type="text" name="q" class="form-control" placeholder="Search..."> <span class="input-group-btn"> <button type="submit" id="search-btn" class="btn btn-flat"> <i class="fa fa-search"></i> </button> </span> </div> </form> </div> <div class="box-body"> <div class="row"> <div class="col-sm-6"> </div> </div> <form action="" method="post"> {% csrf_token %} <div class="input-group" style="width: 220px;margin-bottom: 5px;margin-left: 15px"> <select name="operate" id="operate" class="form-control btn-default"> </select> <span class="input-group-btn"> <button type="submit" class="btn btn-warning btn-flat">Go!</button> </span> </div> <table id="example2" class="table table-bordered table-hover text-center"> <!--==========================第一种方式,手动生成批量修改表============================--> {# <thead>#} {# <tr>#} {# <th style="width: 8%">#} {# <button type="button" class="btn btn-info btn-xs">#} {# <span>批量</span>#} {# <input type="checkbox" name="batch_choose">#} {# </button>#} {# </th>#} {# <th style="width: 5%">序号</th>#} {# <th>学员</th>#} {# <th>考勤</th>#} {# <th>成绩</th>#} {# <th>批语</th>#} {# </tr>#} {# </thead>#} {# <tbody>#} {# {% for record in all_records %}#} {# <tr>#} {# <td><input type="checkbox" name="choose" value="{{ record.pk }}"></td>#} {# <td>{{ forloop.counter }}</td>#} {# <td>{{ record.student }}</td>#} {# <td>{{ record.get_record_display }}</td>#} {# <td>#} {# <select name="score_{{ record.pk }}" id="">#} {# {% for choice in score_choices %}#} {# {% if record.score == choice.0 %}#} {# <option value="{{ choice.0 }}" selected>{{ choice.1 }}#} {# {% else %}#} {# <option value="{{ choice.0 }}">{{ choice.1 }}#} {# {% endif %}#} {# {% endfor %}#} {# </select>#} {# </td>#} {# <td>#} {# <textarea name="homework_note_{{ record.pk }}" id="" cols="16" rows="1" class="form-control">{{ record.homework_note|default:"" }}</textarea>#} {# </td>#} {# </tr>#} {# {% endfor %}#} {# </tbody>#} <!--==========================第二种方式,通过modelformset生成============================--> {{ all_records.management_form }} <!-- 这句话一定要加上,固定的昂 不然会报错['ManagementForm data is missing or has been tampered with'] --> <thead> <tr> <th>姓名</th> <th>考勤</th> <th>作业成绩</th> <th>作业评语</th> </tr> </thead> <tbody> {% for record in all_records %} <tr> {{ record.id }} <td>{{ record.instance.student }}</td> <td>{{ record.instance.get_record_display }}</td> <td>{{ record.score }}</td> <td>{{ record.homework_note }}</td> </tr> {% endfor %} </tbody> </table> <input type="submit" class="btn btn-success pull-right" value="批量提交"> {% if not all_records %} <h3 class="text-center">没有相关记录!</h3> {% endif %} <div class="pull-right" style="display:inline-block; width: 120px;margin: 22px 10px"> {{ jump_tag|safe }} </div> <div class="pull-right"> {{ paginator_tag|safe }} </div> </form> </div> <!-- /.box-body --> </div> <!-- /.box --> </div> <!-- /.col --> </div> {% endblock content %} {% block js %} {{ block.super }} {% endblock js %} {% block customjs %} <script> $("[name=batch_choose]").click(function () { var status = $(this).prop("checked"); $("[name=choose]").prop('checked', status) }); </script> {% endblock customjs %}
批量修改学生学习记录演示