一、课程记录和学习记录

1.初始化 course_record, study_record.
2.学习记录
3.录入成绩
4.显示成绩 ajax 查询 柱状图展示成绩 highcharts

5.上传作业(os模块)
6.下载作业

二、配置study_record

1、给学习记录配置自定义配置

class StudyConfig(ModelStark):
def display_record(self, obj=None, header=False):
if header:
return "签到"
return obj.get_record_display() # 存的值对应的中文 def display_score(self, obj=None, header=False):
if header:
return "成绩"
return obj.get_score_display() # 存的值对应的中文 list_display = ["student", "course_record", display_record, display_score] site.register(StudyRecord, StudentConfig)

  不取字段值而是拼上get和display取存的值对应的中文。

2、修改ModelStark中get_body方法全局处理记录对象包含choices情况

  在models中choices对应的是一个元组。

class ShowList(object):
"""展示页面类"""
def get_body(self):
"""构建表单数据"""
"""代码省略"""
# 针对choices属性
if field_obj.choices:
val = getattr(obj, "get_" + field + "_display")
else:
val = getattr(obj, field) # 拿到的关联对象 处理不了多对多 ##################自定义配置#############
class StudyConfig(ModelStark):
list_display = ["student", "course_record", "record", "score"] site.register(StudyRecord, StudentConfig)

  录入学习记录:

  

三、批量生成学习记录

1、定制CourseRecod批量功能

class CourseRecordConfig(ModelStark):
list_display = ["class_obj", "day_num", "teacher"] def patch_studyRecord(self, request, queryset):
print("=====>",queryset)
"""
提交批量操作获取的queryset
<QuerySet [<CourseRecord: python基础(9期) day94>, <CourseRecord: python基础(9期) day95>]>
"""
temp = []
for course_record in queryset:
# 过滤出班级所有的学生 学生表classlist关联班级表
student_list = Student.objects.filter(class_list__id=course_record.class_obj.pk) # 学生的班级id和课程记录班级的id进行比对 拿到班级所有的学生
for student in student_list: # 拿到学生对象
obj = StudyRecord(student=student, course_record=course_record)
temp.append(obj) StudyRecord.objects.bulk_create(temp) # 批量插入 actions = [patch_studyRecord, ]
patch_studyRecord.short_description = "批量生产学习记录"
"""
def get_action_list(self):
# 获取自定义批量操作
temp = []
for action in self.actions:
temp.append({
"name": action.__name__, # 函数.__name__:拿到函数名
"desc": action.short_description
}) # [{"name": "patch_init", "desc": "批量处理"}]
return temp
""" site.register(CourseRecord, CourseRecordConfig)

  注意

(1)批量插入操作:

StudyRecord.objects.bulk_create(temp)

(2)跨表查询班级所有的学生

# 过滤出班级所有的学生  学生表classlist关联班级表
student_list = Student.objects.filter(class_list__id=course_record.class_obj.pk) # 学生的班级id和课程记录班级的id进行比对 拿到班级所有的学生

  过滤course_record关联的班级对应的所有的学生。

(3)批量操作别名描述short_description

  这是由于在Modelstark中源码get_action_list有关于action别名的配置:

def get_action_list(self):
# 获取自定义批量操作
temp = []
for action in self.actions:
temp.append({
"name": action.__name__, # 函数.__name__:拿到函数名
"desc": action.short_description
}) # [{"name": "patch_init", "desc": "批量处理"}]
return temp

2、批量生成学习记录

  

  学习记录生产成功:

  

四、学习记录筛选查看

1、studyrecord/?course_record=%s过滤

  根据课程记录来过滤学习记录,这个需要修改service/stark.py中的get_filter_condition。因为这个其实也是一种filter过滤,但并没有写在filter_list中。

class ModelStark(object):
def get_filter_condition(self, request):
"""拿到过滤条件"""
filter_condition = Q() # 默认查询条件为且 and for filter_field, val in request.GET.items(): # 过滤字段、查询的值 去除fitler_field拼接的__id
# if filter_field in self.list_filter: # 仅限过滤使用,只处理filter过滤列表的键值
if filter_field != "page": # (分页等排除) ?page=2&course_record=1
filter_condition.children.append((filter_field, val)) # 添加的是一个元组 return filter_condition

  修改后仅排除了?page=1这样的情况,可以在页面上访问http://127.0.0.1:8000/stark/crm/studyrecord/?course_record=2拿到过滤结果:

  

2、添加按钮实现条件过滤查看

class CourseRecordConfig(ModelStark):
# 定制一栏新的表格
def record(self, obj=None, header=False):
if header:
return "checked"
return mark_safe("<a href='/stark/crm/studyrecord/?course_record=%s'>记录</a>" % obj.pk) # mark_safe取消转义 list_display = ["class_obj", "day_num", "teacher", record] def patch_studyRecord(self, request, queryset):
temp = []
for course_record in queryset:
# 过滤course_record关联的班级对应的所有的学生 学生表classlist关联班级表
student_list = Student.objects.filter(class_list__id=course_record.class_obj.pk) # 学生的班级id和课程记录班级的id进行比对 拿到班级所有的学生
for student in student_list: # 拿到学生对象
obj = StudyRecord(student=student, course_record=course_record)
temp.append(obj)
StudyRecord.objects.bulk_create(temp) # 批量插入 actions = [patch_studyRecord, ]
patch_studyRecord.short_description = "批量生产学习记录" site.register(CourseRecord, CourseRecordConfig)

  课程记录页面:

  

  点击记录跳转学习记录页面:

  

五、考勤点名

  给学习记录订制迟到批量操作

class StudyConfig(ModelStark):
list_display = ["student", "course_record", "record", "score"]
def patch_late(self, request, queryset):
queryset.update(record="late") patch_late.short_description = "迟到"
actions = [patch_late, ] site.register(StudyRecord, StudyConfig)

  批量调整上课记录为迟到:

  

六、录入成绩

1、在课程记录页面添加录入成绩栏(扩展新的url)

class CourseRecordConfig(ModelStark):
def score(self, request, course_record_id):
return HttpResponse("score") def extra_url(self):
"""扩展考勤记录url"""
temp = []
temp.append(url(r"record_score/(\d+)", self.score))
return temp # 定制一栏新的表格
def record(self, obj=None, header=False):
if header:
return "考勤"
return mark_safe("<a href='/stark/crm/studyrecord/?course_record=%s'>记录</a>" % obj.pk) # mark_safe取消转义 def record_score(self, obj=None, header=False):
if header:
return "录入成绩"
# http://127.0.0.1:8000/stark/crm/studyrecord/?course_record=1 CourseRecord主键值
return mark_safe("<a href='record_score/%s'>录入成绩</a>" % obj.pk) list_display = ["class_obj", "day_num", "teacher", record, record_score] def patch_studyRecord(self, request, queryset):
"""代码省略"""

注意:

(1)定制record_score函数添加录入成绩项目栏

def record_score(self, obj=None, header=False):
if header:
return "录入成绩"
# http://127.0.0.1:8000/stark/crm/studyrecord/?course_record=1 CourseRecord主键值
return mark_safe("<a href='record_score/%s'>录入成绩</a>" % obj.pk)

(2)定制录入成绩扩展路由和视图

def score(self, request, course_record_id):
return HttpResponse("score") def extra_url(self):
"""扩展考勤记录url"""
temp = []
temp.append(url(r"record_score/(\d+)", self.score))
return temp

(3)测试验证

  

  点击录入成绩,跳转对应页面:

  

2、处理score视图函数

class CourseRecordConfig(ModelStark):
def score(self, request, course_record_id):
study_record_list = StudyRecord.objects.filter(course_record=course_record_id) # 过滤出对应课程(哪个班级哪一天)的学习记录 score_choices = StudyRecord.score_choices
return render(request, "score.html", locals())

注意:

(1)study_record_list拿到对应课程的学习记录(哪一天哪个班级)

(2)score_choices拿到StudyRecord的score_choices字段内容传递给模板

3、构建录入成绩页面

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
<script src="/static/js/jquery-1.12.4.min.js"></script>
</head>
<body>
<h3>录入成绩</h3>
<div class="container">
<div class="row">
<div class="col-md-9 col-md-offset-1">
<form action="" method="post">
{% csrf_token %}
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>学生姓名</th>
<th>考勤</th>
<th>成绩</th>
<th>批语</th>
</tr>
</thead>
<tbody>
{% for study_record in study_record_list %}
<tr>
<td>{{ study_record.student }}</td>
{# <td>{{ study_record.record }}</td> 针对带有choices的字段使用拼接get和display #}
<td>{{ study_record.get_record_display }}</td>
<td style="width: 150px; padding: 10px 20px;">
<select name="" id="" class="form-control">
{% for item in score_choices %}
<option value="{{ item.0 }}">{{ item.1 }}</option>
{% endfor %}
</select>
</td>
<td>
<textarea name="" id="" cols="30" rows="4" class="form-control"></textarea>
</td>
</tr>
{% endfor %} </tbody>
</table>
<input type="submit" class="btn btn-default pull-right">
</form>
</div>
</div>
</div>
</body>
</html>

score.html

注意:

(1)考勤栏显示中文

  针对Model中的record字段:

record = models.CharField("上课纪录", choices=record_choices, default="checked", max_length=64)

  要显示迟到签到信息需要拼接get和display取值

{# <td>{{ study_record.record }}</td>   针对带有choices的字段使用拼接get和display #}
<td>{{ study_record.get_record_display }}</td>

  显示效果:

  

(2)成绩显示为一个个option对象点选操作

<td style="width: 150px; padding: 10px 20px;">
<select name="score" id="" class="form-control">
{% for item in score_choices %}
<option value="{{ item.0 }}">{{ item.1 }}</option>
{% endfor %}
</select>
</td>

  item.0拿到score_choices中每个元组的第一个值即分数,item.1拿到元组第二个值即评分等级。显示效果如下:

  

(3)用textarea渲染批语栏

<td>
<textarea name="homework_note" id="" cols="30" rows="4" class="form-control"></textarea>
</td>

  显示效果如下所示:

  

(4)订制表单和提交按钮

<body>
<h3>录入成绩</h3>
<div class="container">
<div class="row">
<div class="col-md-9">
<form action="" method="post">
{% csrf_token %}
<table class="table table-bordered table-striped"....>
<input type="submit" class="btn btn-default pull-right">
</form>
</div>
</div>
</div>
</body>

  显示效果:

  

4、视图函数处理post请求

class CourseRecordConfig(ModelStark):
def score(self, request, course_record_id):
if request.method == "POST":
# print(request.POST)
# <QueryDict: {'csrfmiddlewaretoken': ['20Zp72PlKJzRZ6HAYkMX0veCIxynx5nogd8LsKKkdZb7mRLrAb1KtN1PDTljh7Jq'], 'score_4': ['70'], 'homework_note_4': ['学习理解能力差'], 'score_5': ['40'], 'homework_note_5': ['无纪律无组织'], 'score_6': ['90'], 'homework_note_6': ['学习能力优秀']}>
for key, value in request.POST.items():
if key == "csrfmiddlewaretoken":
continue
# 分隔score_1为例,score为字段 1为某一个学生学习记录的pk值
field, pk = key.rsplit("_", 1) # 从右开始以"_"分隔数据,且仅分隔一次
if field == "score":
StudyRecord.objects.filter(pk=pk).update(score=value)
else:
StudyRecord.objects.filter(pk=pk).update(homework_note=value)
return redirect(request.path) # 拿到当前POST请求路径重定向GET请求
else:
study_record_list = StudyRecord.objects.filter(course_record=course_record_id) # 过滤出对应课程(哪个班级哪一天)的学习记录 score_choices = StudyRecord.score_choices
return render(request, "score.html", locals())

  同时还伴随有score.html的变更:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
<script src="/static/js/jquery-1.12.4.min.js"></script>
</head>
<body>
<h3>录入成绩</h3>
<div class="container">
<div class="row">
<div class="col-md-9 col-md-offset-1">
<form action="" method="post">
{% csrf_token %}
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>学生姓名</th>
<th>考勤</th>
<th>成绩</th>
<th>批语</th>
</tr>
</thead>
<tbody>
{% for study_record in study_record_list %}
<tr>
<td>{{ study_record.student }}</td>
{# <td>{{ study_record.record }}</td> 针对带有choices的字段使用拼接get和display #}
<td>{{ study_record.get_record_display }}</td>
<td style="width: 150px; padding: 10px 20px;">
<select name="score_{{ study_record.pk }}" id="" class="form-control">
{% for item in score_choices %}
{% if study_record.score == item.0 %}
{# 当前成绩等于item.0#}
<option selected value="{{ item.0 }}">{{ item.1 }}</option>
{% endif %}
<option value="{{ item.0 }}">{{ item.1 }}</option>
{% endfor %}
</select>
</td>
<td>
<textarea name="homework_note_{{ study_record.pk }}" id="" cols="30" rows="4"
class="form-control">{{ study_record.homework_note }}</textarea>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<input type="submit" class="btn btn-default pull-right">
</form>
</div>
</div>
</div>
</body>
</html>

(1)分析表单提交的数据

  直接在上面的成绩录入页面提交POST请求:

  

  在视图中接收POST请求,打印接收的request.POST数据:

class CourseRecordConfig(ModelStark):
def score(self, request, course_record_id):
if request.method == "POST":
print(request.POST)
"""
<QueryDict: {'csrfmiddlewaretoken': ['UMfON3mW1TKIMCqWI3fqOUuRaqP9ggoL8Zoa8LhVu9mY9nuNkUudhch45MC50iKN'],
'score': ['60', '80', '90'], 'homework_note': ['朽木不可雕', '学习自觉性较差', '学习认真刻苦']}>
"""
return HttpResponse("123")

  这是由于所有的成绩select标签name="score",所有批语textarea标签name="homework_note",一个键对应三个值,三个值组成数组。导致无法区分谁是谁的成绩和批语。

(2)修改select标签和textarea标签name生成规则

<td style="width: 150px; padding: 10px 20px;">
<select name="score_{{ study_record.pk }}" id="" class="form-control">
{% for item in score_choices %}
<option value="{{ item.0 }}">{{ item.1 }}</option>
{% endfor %}
</select>
</td>
<td>
<textarea name="homework_note_{{ study_record.pk }}" id="" cols="30" rows="4" class="form-control"></textarea>
</td>

  重新提交表单,request.POST获取的数据如下:

class CourseRecordConfig(ModelStark):
def score(self, request, course_record_id):
if request.method == "POST":
print(request.POST)
# <QueryDict: {'csrfmiddlewaretoken': ['20Zp72PlKJzRZ6HAYkMX0veCIxynx5nogd8LsKKkdZb7mRLrAb1KtN1PDTljh7Jq'], 'score_4': ['70'], 'homework_note_4': ['学习理解能力差'], 'score_5': ['40'], 'homework_note_5': ['无纪律无组织'], 'score_6': ['90'], 'homework_note_6': ['学习能力优秀']}>

  如上所示键带有自己的id值,可以更好地去录入成绩,完成处理更新操作。

(3)splice()和rsplice方法

  Python split() 通过指定分隔符对字符串进行切片,如果参数 num 有指定值,则仅分隔 num 个子字符串。

print("yuan_alex_egon".split("_", 1))   # 只分一次
print("yuan_alex_egon".split("_", 2)) # 分两次
print("yuan_alex_egon".rsplit("_",1)) # 从右边开始分一次
"""
['yuan', 'alex_egon']
['yuan', 'alex', 'egon']
['yuan_alex', 'egon']
"""

(4)循环处理reques.POST

for key, value in request.POST.items():
if key == "csrfmiddlewaretoken":
continue
# 分隔score_1为例,score为字段 1为某一个学生学习记录的pk值
field, pk = key.rsplit("_", 1) # 从右开始以"_"分隔数据,且仅分隔一次
if field == "score":
StudyRecord.objects.filter(pk=pk).update(score=value)
else:
StudyRecord.objects.filter(pk=pk).update(homework_note=value)

(5)重定向到POST请求当前页面

def score(self, request, course_record_id):
if request.method == "POST":
"""代码省略"""
return redirect(request.path) # 拿到当前POST请求路径重定向GET请求

(6)get页面渲染显示之前提交信息为默认值

<td style="width: 150px; padding: 10px 20px;">
<select name="score_{{ study_record.pk }}" id="" class="form-control">
{% for item in score_choices %}
{% if study_record.score == item.0 %}
{# 当前成绩等于item.0#}
<option selected value="{{ item.0 }}">{{ item.1 }}</option>
{% endif %}
<option value="{{ item.0 }}">{{ item.1 }}</option>
{% endfor %}
</select>
</td>
<td>
<textarea name="homework_note_{{ study_record.pk }}" id="" cols="30" rows="4" class="form-control">{{ study_record.homework_note }}</textarea>
</td>

  这样在POST请求提交后,get请求获取的当前页面,页面保留之前录入的数据。

5、数据结构调整性能优化

class CourseRecordConfig(ModelStark):
def score(self, request, course_record_id):
if request.method == "POST":
data = {}
for key, value in request.POST.items(): # 键、值
if key == "csrfmiddlewaretoken":
continue
# 分隔score_1为例,score为字段 1为某一个学生学习记录的pk值
field, pk = key.rsplit("_", 1) # 从右开始以"_"分隔数据,且仅分隔一次 字段、主键 # dic = {1:{"homework_note":"", "score":90}, 2:{"homework_note": "", "score": 76}}
if pk in data:
# 第一次加入字典
data[pk][field] = value
else:
# pk已经保存在字典中
data[pk] = {field: value} print("data", data) # data {'4': {'score': '100', 'homework_note': 'dsfe '}, '5': {'score': '85', 'homework_note': 'asd a'}, '6': {'score': '50', 'homework_note': 'adad w'}} for pk, update_data in data.items(): # 主键、更新数据
StudyRecord.objects.filter(pk=pk).update(**update_data) return redirect(request.path) # 拿到当前POST请求路径重定向GET请求

(1)将数据调整为字典套字典的格式

def score(self, request, course_record_id):
if request.method == "POST":
data = {}
for key, value in request.POST.items(): # 键、值
if key == "csrfmiddlewaretoken":
continue
# 分隔score_1为例,score为字段 1为某一个学生学习记录的pk值
field, pk = key.rsplit("_", 1) # 从右开始以"_"分隔数据,且仅分隔一次 字段、主键 # dic = {1:{"homework_note":"", "score":90}, 2:{"homework_note": "", "score": 76}}
if pk in data:
# 第一次加入字典
data[pk][field] = value
else:
# pk已经保存在字典中
data[pk] = {field: value} print("data", data) # data {'4': {'score': '100', 'homework_note': 'dsfe '}, '5': {'score': '85', 'homework_note': 'asd a'}, '6': {'score': '50', 'homework_note': 'adad w'}}

(2)更新数据

for pk, update_data in data.items():   # 主键、更新数据
StudyRecord.objects.filter(pk=pk).update(**update_data)

  update()方法对于任何结果集均有效,可以同时更新多条记录。

七、显示成绩 ajax 查询 柱状图展示成绩 highcharts

1、给学生表定制成绩查询(扩展视图和url)

class StudentConfig(ModelStark):
def score_view(self, request, sid): # sid:当前学生的id
"""扩展视图"""
student = Student.objects.filter(pk=sid).first()
class_list = student.class_list.all() # 班级列表
return render(request, "score_view.html", locals()) def extra_url(self):
"""扩展路由"""
temp = []
temp.append(url((r"score_view/(\d+)"), self.score_view))
return temp def score_show(self, obj=None, header=False):
"""查看成绩"""
if header:
return "查看成绩"
return mark_safe("<a href='/stark/crm/student/score_view/%s'>查看成绩</a>" % obj.pk) list_display = ['customer', 'class_list', score_show]
list_display_links = ['customer'] site.register(Student, StudentConfig)

  显示效果:

  

2、成绩展示模板设计

  score_view.html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
<script src="/static/js/jquery-1.12.4.min.js"></script>
</head>
<body>
<h3>查看{{ student }}成绩</h3>
<div class="container">
<div class="row">
<div class="col-md-9 col-md-offset-1">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>班级</th>
<th>班主任</th>
<th>任课老师</th>
<th>课程成绩</th>
</tr>
</thead>
<tbody>
{% for cls in class_list %}
<tr>
{# 班级名称:class_list.__str__ #}
<td>{{ cls }}</td>
<td>{{ cls.tutor }}</td>
<td>
{% for teacher in cls.teachers.all %}
<span>{{ teacher }}</span>,
{% endfor %}
</td>
<td>
<a class="check_chart"><span>点击查看</span></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>

  展示效果:

  

3、给点击查看绑定事件

<script>
// check_chart绑定事件
$(".check_chart").click(function () {
$.ajax({
url: "", // 走当前
type: "get",
data:{
sid: $(this).attr("sid"),
cid: $(this).attr("cid"),
},
success:function (data) {
console.log(data);
}
})
})
</script>

(1)给点击查看a标签添加sid和cid属性

<td>
<a class="check_chart" cid="{{ cls.pk }}" sid="{{ student.pk }}"><span>点击查看</span></a>
</td>

  其中sid是学生id,cid是班级id。

(2)给视图发送ajax,获取学生对应课程的所有学习记录

class StudentConfig(ModelStark):
def score_view(self, request, sid): # sid:当前学生的id
"""扩展视图"""
if request.is_ajax():
# 处理ajax请求
print(request.GET)
sid = request.GET.get("sid")
cid = request.GET.get("cid")
# 去studyrecord查看学生对应课程所有学习记录 课程需要跨表查询
study_record_list = StudyRecord.objects.filter(student=sid, course_record__class_obj=cid)
else:
student = Student.objects.filter(pk=sid).first()
class_list = student.class_list.all() # 班级列表
return render(request, "score_view.html", locals())

4、使用highchart插件显示成绩

(1)下载引入highchart

  地址:https://www.hcharts.cn下载程序包后,将压缩包下code文件夹拷贝到项目crm/static目录下,并改名为chart.

  

  在score_view.html中引入highcharts.js:

<head>
#省略#
<script src="/static/chart/highcharts.js"></script>
</head>

(2)设计柱状图

  

(3)将显示柱状图放入ajax中处理

<body>
<h3>查看{{ student }}成绩</h3>
<div class="container"...>
<div id="container" style="min-width:400px;height:400px"></div>
<script>
// check_chart绑定事件
$(".check_chart").click(function () {
$.ajax({
url: "", // 走当前
type: "get",
data: {
sid: $(this).attr("sid"),
cid: $(this).attr("cid"),
},
success: function (data) {
// 显示柱状图
var chart = Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: '查看成绩'
},
subtitle: {
text: '数据截止 2017-03,来源: <a href="https://en.wikipedia.org/wiki/List_of_cities_proper_by_population">Wikipedia</a>'
},
xAxis: { // 横坐标
type: 'category',
labels: {
rotation: -45 // 设置轴标签旋转角度
}
},
yAxis: { // 纵坐标
min: 0,
title: {
text: '分数'
}
},
legend: {
enabled: false
},
tooltip: { // 鼠标悬浮显示
pointFormat: '分数: <b>{point.y:.2f}</b>'
},
series: [{
name: '成绩',
data: data,
dataLabels: {
enabled: true,
rotation: -90,
color: '#FFFFFF',
align: 'right',
format: '{point.y:.1f}', // :.1f 为保留 1 位小数
y: 10
}
}]
});
}
})
})
</script>
</body>

5、在视图处理出highcharts模板要求的data数据

from django.http import JsonResponse

class StudentConfig(ModelStark):
def score_view(self, request, sid): # sid:当前学生的id
"""扩展视图"""
if request.is_ajax():
# 处理ajax请求
print(request.GET)
sid = request.GET.get("sid")
cid = request.GET.get("cid")
# 去studyrecord查看学生对应课程所有学习记录 课程需要跨表查询
study_record_list = StudyRecord.objects.filter(student=sid, course_record__class_obj=cid) data_list = []
for study_record in study_record_list:
day_num = study_record.course_record.day_num # 天数
data_list.append(["day%s" % day_num, study_record.score]) # 和highchart的data要求格式相同列表包列表
print(data_list) # [['day1', -1], ['day95', 80]]
return JsonResponse(data_list, safe=False) # 序列化不是一个字典必须改为False
else: student = Student.objects.filter(pk=sid).first()
class_list = student.class_list.all() # 班级列表
return render(request, "score_view.html", locals())

  注意要将数据组织为 [['day94', 100], ['day95', 50], ['day92', 85], ['day91', 90]] 这样的形式。且使用JsonResponse进行序列化,在系列化的不是一个字典时,需要修改safe=False。

6、显示效果

  

CRM——讲师与学生的更多相关文章

  1. 2 CRM 讲师与学生,highcharts应用

    一.讲师与学生简介 1 初始化 course_record,studyrecord, 2 考勤 3 录入成绩 4 显示成绩 ajax 查询 5 上传作业(os模块) 6 下载作业 二. 初始化 ,st ...

  2. CRM - 讲师与学生

    一.讲师与学生简介 1.初始化 course_record, study_record.2.学习记录3.录入成绩4.显示成绩 ajax 查询 柱状图展示成绩 highcharts 5.上传作业(os模 ...

  3. Django项目:CRM(客户关系管理系统)--79--69PerfectCRM实现CRM业务流程(bpm)学生讲师分页

    # student_views.py # ————————60PerfectCRM实现CRM学生上课记录———————— from django.shortcuts import render #页面 ...

  4. Django项目:CRM(客户关系管理系统)--73--63PerfectCRM实现CRM讲师下载作业

    # teacher_urls.py # ————————62PerfectCRM实现CRM讲师讲课记录———————— from django.conf.urls import url from bp ...

  5. Django项目:CRM(客户关系管理系统)--72--62PerfectCRM实现CRM讲师讲课记录

    #urls.py """PerfectCRM URL Configuration The `urlpatterns` list routes URLs to views. ...

  6. Django - 学习目录

    Django 基础 web应用/http协议/web框架 Django简介 Django - 路由层(URLconf) Django - 视图层 Django - 模板层 Django - 模型层 - ...

  7. python全栈开发之路

    一.Python基础 python简介 python数据类型(数字\字符串\列表) python数据类型(元组\字典) python数据类型(集合) python占位符%s,%d,%r,%f prin ...

  8. CRM系统(第二部分)

      阅读目录 一.讲师与学生简介 二. 初始化 ,studyrecord, 三.初始化 course_record:批量生成学习记录 四. 考勤  url跳转 五.录入成绩 六.highcharts表 ...

  9. 10.23 crm(3)

    2018-10-23 20:34:30 继续增加新的功能!在代码注释里面有! 越努力,越幸运!永远不要高估自己! 还有明天再加上rbca权限管理系统就完美了! 然后crm做完,再过几天不挂针一切好了也 ...

随机推荐

  1. UML之用例图详解

    原文链接:https://blog.csdn.net/mj_ww/article/details/53020080 UML,即Unified Model Language,统一建模语言.百度百科对他的 ...

  2. 3-19bug随即

    #方案录入 ### 国外网络访问,录入添加图片,上传后图片显示不出. ``` * 后台有返回数据,前端显示巨慢,待检查 * ``` ### 产品信息,富文本信息加载不出

  3. Win7 如何阻止程序联网

    https://jingyan.baidu.com/article/9113f81b03d4e12b3214c7c3.html

  4. 获取select text 值 得获取选中的option

    $("#magSeaTypeSelect option:selected").text();

  5. Android 数据库框架GreenDao使用

    1.GreenDao3介绍 (1)基本概念 (2)GreenDao3工作原理 (3)GreenDao优点 (4)GreenDao3版本的改进 2.GreenDao3的相关配置概念介绍 (1)配置项目( ...

  6. springmvc相关配置和用法

    目录如下: 一.spring mvc 核心类与接口 二.spring mvc 核心流程图 三.spring mvc DispatcherServlet说明 四.spring mvc 父子上下文的说明 ...

  7. notepad++配置编译运行java

    点击插件->Plugin Manager->show plugin manager : 选择NppExec,选择install,就将这个插件下载下来了. 这个时候会重启notepad++: ...

  8. pip不是内部或外部命令也不是可运行的程序或批处理文件的问题

    当我用windows电脑 pip install missingno 时 它居然会报pip不是内部或外部命令也不是可运行的程序或批处理文件的问题! 解决方法: 1)找到 pip.exe 所在位置,一般 ...

  9. Notepad++编译和运行Java

    首先要让Notepad++编译和运行Java,前提是电脑里已经配置好了Java的环境(这里可以参考我博客里关于Java环境配置的那篇随笔). 在Notepad++上面的选项栏中找到 插件---> ...

  10. Linux设备驱动开发基础--阻塞型设备驱动

    1. 当一个设备无法立刻满足用户的读写请求时(例如调用read时,设备没有数据提供),驱动程序应当(缺省的)阻塞进程,使它进入等待(睡眠)状态,知道请求可以得到满足. 2. Linux内核等待队列:在 ...