1、表结构

class Student(models.Model):
"""
学生表(已报名)
"""
customer = models.OneToOneField(verbose_name='客户信息', to='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)
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)
date = models.DateField(verbose_name='入职时间', help_text='格式yyyy-mm-dd', 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='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):
'''
学生学习记录
'''
student = models.ForeignKey(verbose_name="学员", to='Student',on_delete=models.CASCADE)
classstudyrecord = models.ForeignKey(verbose_name="第几天课程", to="ClassStudyRecord",on_delete=models.CASCADE)
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) def __str__(self):
return "{0}-{1}".format(self.classstudyrecord, self.student) class Meta:
unique_together=["student","classstudyrecord"] # 学生记录表是由上课记录表批量生成的

数据模型

表结构分析:
1、学生学习记录表和学生表是多对一的关系;一个学生有多条学习记录
2、学生学习记录和班级记录是多对一的关系;一条班级记录是这个班所有学生的学习记录

2、实现功能

班级记录:

学生学习详细记录:

批量创建:
1、获取所有班级的班级记录展示到前端页面;
2、前端批量选择班级记录,提交到后端,前端提交时携带着每个班级记录的pk值;
3、后端通过前端提交过来的pk值连表找到每个班级的所有学生;
4、批量将每个班级的上课记录添加给这个班的每一个学生; 批量更新:
批量更新时需要注意,由于我们是批量修改的,所以前端在提交数据的时候必须标明我们修改的是哪个学生的学习记录,一般我们用这个学生的id来标注,这样后端在更新数据的时候就拿着这个学生的id去更新

自定义版本批量更新

# 批量将班级记录更新给这个班级的每个学生
class Class_study_records(View):
# 展示上课记录表内容
def get(self, request):
class_obj = models.ClassStudyRecord.objects.all()
return render(request, "class_study_records.html", {"class_obj": class_obj}) # 批量将班级的上课记录添加给班级的所有学生
def post(self, request):
action = request.POST.get("action")
selected_id = request.POST.getlist("selected_id")
if hasattr(self, action):
getattr(self, action)(selected_id)
# 这样返回页面减少一次重定向
return self.get(request) # 批量创建学生学习记录
def batch_record(self, selected_id):
# 循环每一个班级的上课记录
for record in selected_id:
# 通过班级记录找到班级的所有学生
all_student = models.ClassStudyRecord.objects.get(pk=record).class_obj.students.all()
li = []
# 将班级记录添加给班级的所有学生
for student in all_student:
obj = models.StudentStudyRecord(
student=student,
classstudyrecord_id=record
)
li.append(obj)
models.StudentStudyRecord.objects.bulk_create(li) # 自定义版本
# 批量更新学生学习记录
class Student_study_records(View):
def get(self, request, record_id):
# 通过前端发过来的班级记录的id找到该班级
class_obj = models.ClassStudyRecord.objects.get(pk=record_id)
# 找到这个课程记录所生成的所有学生学习记录
student_obj = models.StudentStudyRecord.objects.filter(
classstudyrecord=class_obj)
# 通过调用类中的属性找到所有可以选择的成绩
score_choices = models.StudentStudyRecord.score_choices
return render(request, "student_study_records1.html",
{"student_obj": student_obj, "class_obj": class_obj, "score_choices": score_choices}) # 因为form表单是在当前页提交,url会带有一个id值,
def post(self, request, record_id):
student_dic = request.POST
# print(student_dic)
# <QueryDict: {'csrfmiddlewaretoken': ['igIDxQDr1xLFmyRGXpmtED6aE9AOtyQosGJq1WI5VNabN07O1aQuLzO6G9mWLNaK'], 'score_11': ['60'], 'homework_note_11': ['1'], 'score_12': ['0'], 'homework_note_12': ['2']}>
"""
{
1:{'score':85,'homework_note':'333'},
2:{'score':85,'homework_note':'333'}
}
"""
data_dict = {}
for key, value in student_dic.items():
if key == "csrfmiddlewaretoken":
continue
field, pk = key.rsplit("_", 1)
# 往字典中的同一个key里,插入多条value,防止第二次添加的把第一条数据替换掉
if pk in data_dict:
data_dict[pk][field] = value
else:
data_dict[pk] = {
field: value,
}
for spk, sdata in data_dict.items():
models.StudentStudyRecord.objects.filter(**{"pk": spk}).update(**sdata)
return self.get(request, record_id)

逻辑 函数

{% extends "template.html" %}
{% block countent %} <section class="content">
<div class="row">
<div class="col-xs-12">
<div class="box"> <form action="" method="post">
{% csrf_token %}
<select name="action" id="" class="form-control" style="width: 200px;display: inline-block;margin-top: 10px;margin-left: 9px">
<option value="batch_record">批量更新学生学习记录</option> </select>
<input type="submit" value="go" class="btn btn-danger" style="vertical-align: 1px"> <!-- /.box-header -->
<div class="box-body">
<table id="example2" class="table table-bordered table-hover">
<thead>
<tr>
<th>
<input type="checkbox" id="choice">
</th>
<th>序号</th>
<th>班级</th>
<th>节次</th>
<th>讲师</th>
<th>课程标题</th>
<th>学生学习详细记录</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for record in class_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 "student_study_records" record.pk %}">详细记录</a></td>
<td>
<a href=""
class="btn btn-primary btn-sm">编辑</a>
<a href=""
class="btn btn-danger btn-sm">删除</a>
</td>
</tr>
{% endfor %} </tbody>
</table>
</div>
</form>
<!-- /.box-body -->
</div>
<!-- /.box --> <!-- /.box -->
</div>
<!-- /.col -->
</div>
<!-- /.row -->
</section>
{% endblock %}
{% block js %}
$("#choice").click(function () {
// 获取当前选中的状态true或false
var state = $(this).prop("checked");
$("[name=selected_id]").prop("checked",state)
})
{% endblock %}

班级记录页面展示

{% extends "template.html" %}
{% block countent %}
<h3>班级:{{ class_obj.class_obj }}第{{ class_obj.day_num }}天</h3>
<div class="container-fluid">
<form action="" method="post">
{% csrf_token %}
<input type="submit" value="提交">
<table class="table table-hover table-bordered ">
<thead>
<tr>
<th>序号</th>
<th>学员</th>
<th>第几天课程</th>
<th>上课记录</th>
<th>本节成绩</th>
<th>批语</th>
</tr>
</thead>
<tbody>
{% for student in student_obj %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ student.student }}</td>
<td>{{ student.classstudyrecord }}</td>
<td>
{{ student.get_record_display }}
</td>
<td>
<select name="score_{{ student.pk }}" id="">
{% for choices in score_choices %}
{% if student.score == choices.0 %}
<option selected value="{{ choices.0 }}">{{ choices.1 }}</option>
{% else %}
<option value="{{ choices.0 }}">{{ choices.1 }}</option>
{% endif %} {% endfor %} </select>
</td>
<td>
<textarea name="homework_note_{{ student.pk }}" id="" cols="20" rows="1">{{ student.homework_note|default:'' }}</textarea> </td>
</tr>
{% endfor %} </tbody>
</table>
</form>
</div> {% endblock %}

学生学习记录页面展示

modelformset_factory

from django.forms.models import modelformset_factory
from django import forms class StudyRecordDeialModelForm(forms.ModelForm):
class Meta:
model = models.StudentStudyRecord # 指定表
# fields = "__all__"
# 指定验证字段
fields = ["score","homework_note"] # modelformset_factory
class Student_study_records(View):
def get(self, request, record_id):
# 通过前端发过来的班级记录的id找到该班级
class_obj = models.ClassStudyRecord.objects.get(pk=record_id)
# 获取这个班级的所有学生学习记录表
student_obj = models.StudentStudyRecord.objects.filter(classstudyrecord=class_obj)
# 用StudentStudyRecord张表指定哪个modelform,对哪些数据进行加工
form_set_obj = modelformset_factory(model=models.StudentStudyRecord,form=StudyRecordDeialModelForm,extra=0)
# 指定加工表里的哪些数据
formset = form_set_obj(queryset=student_obj)
return render(request, "student_study_records1.html",{"formset":formset}) # form表单是在当前页提交,url会带有一个id值,
def post(self, request, record_id):
# 通过前端发过来的班级记录的id找到该班级
class_obj = models.ClassStudyRecord.objects.get(pk=record_id)
# 获取这个班级的所有学生学习记录表
student_obj = models.StudentStudyRecord.objects.filter(classstudyrecord=class_obj)
# 用StudentStudyRecord张表指定哪个modelform,对哪些数据进行加工
form_set_obj = modelformset_factory(model=models.StudentStudyRecord, form=StudyRecordDeialModelForm, extra=0) # 将前端提交过来的数据交给这个对象去处理
formset = form_set_obj(request.POST)
# modelform对数据进行验证
if formset.is_valid():
# 验证成功保存到数据库
formset.save()
else:
# 打印错误信息
print(formset.errors)
return self.get(request, record_id)

逻辑函数

{% extends "template.html" %}
{% block countent %}
<h3>班级:{{ class_obj.class_obj }}第{{ class_obj.day_num }}天</h3>
<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 }} <!--必须用id不能用pk,用来标识是修改的哪条数据-->
<td>{{ form.instance.student }}</td>
<!--默认样式是下拉选择框,指定instance显示原数据的值-->
{# <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> {% endblock %}

学生学习记录页面展示

注意前端页面渲染时必须加上,固定写法
{{ formset.management_form }} 我们在前端提交数据的时候必须用id来标识我们修改的是哪条数据,用于后端进行识别后保存进数据库,
该字段在前端页面是不显示的;
注意:不能用pk做标识符,pk默认是从0开始的,不能用pk,不能用pk,不能用pk,重要的事情说三遍!!!

Django-批量更新的更多相关文章

  1. Django REST Framework批量更新rest_framework_extensions

    Django REST framework 是一套基于Django框架编写RESTful风格API的组件. 其中mixins配合viewsets能极其方便简化对数据的增删改查, 但本身并没有对数据的批 ...

  2. django orm 更新数据时间不自动更新问题

    gmt_create自动添加auto_now_add:gmt_modify自动更新auto_now class CommonInfo(models.Model): """ ...

  3. SQL批量更新 关系表更新

    很多人在做数据的批量更新时..如果更新的内容是从其他表查出来的..很容易这么写.. UPDATE TABLE1 SET COLUMN1=(SELECT SUM(SOMETHING) FROM TABL ...

  4. SQL 将2张不相关的表拼接成2列,批量更新至另一张表

    update SO_Master set LotteryNo=t2.LotteryNo,UpdateTime=GETDATE() --select sm.LotteryNo,sm.SysNo,t2.L ...

  5. [PDO绑定参数]使用PHP的PDO扩展进行批量更新操作

    最近有一个批量更新数据库表中某几个字段的需求,在做这个需求的时候,使用了PDO做参数绑定,其中遇到了一个坑. 方案选择 笔者已知的做批量更新有以下几种方案: 1.逐条更新 这种是最简单的方案,但无疑也 ...

  6. Ado.net[登录,增删改查,Get传值,全选,不选,批量删除,批量更新]

    [虽然说,开发的时候,我们可以使用各种框架,ado.net作为底层的东西,作为一个合格的程序员,在出问题的时候我们还是要知道如何调试] 一.增删改查 cmd.ExecuteReader();执行查询, ...

  7. MongoDB学习笔记~大叔分享批量添加—批量更新—批量删除

    回到目录 说它是批量操作,就是说将集合对象一次提交到服务器,并对数据进行持久化,如果您的代码是一次一次的提交,那不算是批量操作!在之前的mongodb仓储中并没有对批量更新和批量删除进行实现,而今天在 ...

  8. jdbc-批量插入、批量删除、批量更新

    一.JDBC的批量插入 JDBC批量插入主要用于数据导入和日志记录因为日志一般都是先写在文件下的等.    我用Mysql5.1.5的JDBC driver 分别对三种比较常用的方法做了测试   方法 ...

  9. MYSQL 处理批量更新数据的一些经验。

    首先,我们需要了解下MYSQL CASE EXPRESSION 语法. 手册传送门:http://dev.mysql.com/doc/refman/5.7/en/control-flow-functi ...

  10. mybatis执行批量更新update

    Mybatis的批量插入这里有http://ljhzzyx.blog.163.com/blog/static/38380312201353536375/.目前想批量更新,如果update的值是相同的话 ...

随机推荐

  1. dos(cmd)命令大全(本文摘至于网络)

    命令简介 cmd是command的缩写.即命令行 .       虽然随着计算机产业的发展,Windows 操作系统的应用越来越广泛,DOS 面临着被淘汰的命运,但是因为它运行安全.稳定,有的用户还在 ...

  2. Callable和Future的区别

    Callable 在Java中,创建线程一般有两种方式,一种是继承Thread类,一种是实现Runnable接口.然而,这两种方式的缺点是在线程任务执行结束后,无法获取执行结果.我们一般只能采用共享变 ...

  3. Session Timer机制分析

    Session Timer机制分析 功能介绍 会话初始化协议(SIP)并没有为所建立的会话定义存活机制.尽管用户代理可以通过会话特定的机制判断会话是否超时,但是代理服务器却做不到这点.如此一来,代理服 ...

  4. Linux更新程序脚本

    DATE=$(date +%Y%m%d_%H%M%S) cd /opt/anystreaming/transcoder/ mv dll/libmonitor_service.so "dll/ ...

  5. ES6入门:数据劫持、Proxy、Reflect

    什么是数据劫持 Object数据劫持实现原理 Array数据劫持的实现原理 Proxy.Reflect 一.什么是数据劫持 定义:访问或者修改对象的某个属性时,在访问和修改属性值时,除了执行基本的数据 ...

  6. 6.AOP配置与应用(xml的方式)

    xml 配置 AOP 1.将 拦截其器对象 初始化到容器中 2.<aop:config> <aop:aspect.... <aop:pointcut <aop:befor ...

  7. Airflow安装异常:ERROR: flask-appbuilder 1.12.3 has requirement Flask<2,>=0.12, but you'll have flask 0.11.1 which is incompatible.

    1 详细异常: ERROR: flask-appbuilder 1.12.3 has requirement Flask<2,>=0.12, but you'll have flask 0 ...

  8. apache安装phpMyAdmin

    安装phpMyAdmin 我这里是LAMP环境 安装httpd,和phpMyAdmin,数据库可以yum安装看你自己情况选择安装方式 $ yum -y install httpd phpMyAdmin ...

  9. Paper Reading:Deep Neural Networks for Object Detection

    发表时间:2013 发表作者:(Google)Szegedy C, Toshev A, Erhan D 发表刊物/会议:Advances in Neural Information Processin ...

  10. texture2dArray

    https://medium.com/@calebfaith/how-to-use-texture-arrays-in-unity-a830ae04c98b http://cdn.imgtec.com ...