ModelFormset实现的一个实例
主要实现“批量录入”功能
表关系
上课记录表与学生学习记录表:
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='UserInfo',on_delete=models.CASCADE) date = models.DateField(verbose_name="上课日期", auto_now_add=True) 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=True, verbose_name="本节有作业",) 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): ''' 学生学习记录 ''' record_choices = (('checked', "已签到"), ('vacate', "请假"), ('late', "迟到"), ('noshow', "缺勤"), ('leave_early', "早退"), ) record = models.CharField("上课纪录", choices=record_choices, default="checked", max_length=64) 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'), ) score = models.IntegerField("本节成绩", choices=score_choices, default=-1) 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) 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) student = models.ForeignKey(verbose_name="学员", to='Student', on_delete=models.CASCADE) # 与上课记录表建立外键关联 classstudyrecord = models.ForeignKey(verbose_name="第几天课程", to="ClassStudyRecord", on_delete=models.CASCADE) def __str__(self): return "{0}-{1}".format(self.classstudyrecord, self.student) class Meta: unique_together=["student","classstudyrecord"]
两张表的大致关系如下:

项目大概流程

班级学习记录的模板文件如下
{% extends 'base.html' %}
{% block content %}
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
课程记录
<small>展示</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i> Level</a></li>
<li class="active">Here</li>
</ol>
</section>
<section class="content container-fluid">
<div class="row">
<div class="col-xs-12">
<div class="box">
<a href="" class="btn btn-primary pull-right">添加记录</a>
<form action="" method="post">
{% csrf_token %}
<select name="action" id="" class="form-control" style="width: 200px;display: inline-block">
<option value="batch_create">批量创建学生学习记录</option>
</select>
<button class="btn btn-danger" style="vertical-align: 1px;">go</button>
<div class="box-body">
<table id="example2" class="table table-bordered table-hover">
<thead>
<tr>
<th>
<input type="checkbox" id="choose">
</th>
<th>序号</th>
<th>班级</th>
<th>节次</th>
<th>老师</th>
<th>本节课程标题</th>
<th>学详</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for record in all_obj %}
<tr>
<td><input type="checkbox" name="selected_id" 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 }}</td>
<td><a href="{% url 'study_decord' record.pk %}">学详</a></td>
<td>
<a href="" class="btn btn-warning btn-xs">编辑</a>
<a href="" class="btn btn-danger btn-xs">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /.box-body -->
</form>
</div>
<!-- /.box -->
</div>
<!-- /.col -->
</div>
<!-- /.row -->
</section>
</div>
{% endblock %}
{% block js %}
<script>
$('#choose').click(function () {
var status = $(this).prop('checked');
$('[name=selected_id]').prop('checked', status);
})
</script>
{% endblock %}
点击“学习详情”后的路由如下
#学详路径 url(r'^study_decord/(\d+)/', views.StudyRecordDeialView.as_view(), name='study_decord'),
具体的视图函数中的处理在下面介绍:
ModelFormset的写法以及视图函数的写法
—— 这里把ModelFormset与视图函数写在一起了
#modelformset from django.forms.models import modelformset_factory from django import forms
# 这个是modelformset的写法 class StudyRecordDeialModelForm(forms.ModelForm): class Meta: model = models.StudentStudyRecord # fields = '__all__' fields = ['score','homework_note'] # 这个是批量处理学生成绩的视图函数 class StudyRecordDeialView(View): def get(self, request, class_record_id): class_record_obj = models.ClassStudyRecord.objects.get(pk=class_record_id) all_study_recored = models.StudentStudyRecord.objects.filter( classstudyrecord=class_record_obj, ) # 这个form_set_obj其实是一个类~工厂模式产出的一个modelformset的类 form_set_obj = modelformset_factory(model=models.StudentStudyRecord,form=StudyRecordDeialModelForm,extra=0) formset = form_set_obj(queryset=all_study_recored) return render(request, 'student/study_record_detail.html',{'formset': formset}) def post(self, request, class_record_id): class_record_obj = models.ClassStudyRecord.objects.get(pk=class_record_id) all_study_recored = models.StudentStudyRecord.objects.filter( classstudyrecord=class_record_obj, ) form_set_obj = modelformset_factory(model=models.StudentStudyRecord, form=StudyRecordDeialModelForm, extra=0) formset = form_set_obj(request.POST) if formset.is_valid(): formset.save() else: print(formset.errors) return redirect(reverse('study_decord',args=(class_record_id,)))
学生学习成绩批量操作前端模板渲染
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
</head>
<body>
<h3>录入{{ class_record_obj.class_obj }}day{{ class_record_obj.day_num }}成绩</h3>
<hr>
<div class="panel panel-default">
<div class="panel-heading">学习记录</div>
<div class="panel-body">
<div style="width: 680px;margin: 0 auto;">
<form method="post" action="">
{% csrf_token %}
<!-- 这句话一定要加上,固定的!!! -->
{{ formset.management_form }}
<table class="table table-bordered">
<thead>
<tr>
<th>姓名</th>
<th>考勤</th>
<th>作业成绩</th>
<th>作业评语</th>
</tr>
</thead>
<tbody>
{% for form in formset %}
<tr>
{{ form.id }}
<td>{{ form.instance.student }}</td>
{# <td>{{ form.instance.student }}</td> #}
<td>{{ form.instance.get_record_display }} </td>
{# <td>{{ form.instance.get_record_display }} </td> #}
<td>{{ form.score }} </td>
<td>{{ form.homework_note }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<input type="submit" value="保存">
</form>
</div>
</div>
</div>
<hr>
</body>
</html>
实现的效果如下

浙公网安备 33010602011771号