CRM - 讲师与学生
一、讲师与学生简介
1.初始化 course_record, study_record.
2.学习记录
3.录入成绩
4.显示成绩 ajax 查询 柱状图展示成绩 highcharts 5.上传作业(os模块)
6.下载作业
二、初始化course_record,study_record
录入courserecord数据

三、批量生成学习记录


知识点
1. 与course_record 关联得班级对应得学生
students_list = Student.objects.filter(class_list__id = course_record.class_obj.pk)
for student in students_list:
student_obj = StudyRecord(course_record=course_record,student=student)
temp.append(student_obj)
2. 批量插入
StudyRecord.objects.bulk_create(temp)
def patch_studyrecord(self,request,queryset):
# print('queryset:--》',queryset)
temp = []
for course_record in queryset:
# 与course_record 关联得班级对应得学生
students_list = Student.objects.filter(class_list__id = course_record.class_obj.pk)
for student in students_list:
student_obj = StudyRecord(course_record=course_record,student=student)
temp.append(student_obj) StudyRecord.objects.bulk_create(temp) actions = [patch_studyrecord]
patch_studyrecord.short_description = "批量生成学习记录"
四、查看学习记录

知识点
1. ?course_record=%s 过滤;
mark_safe("<a href='/stark/crm/studyrecord/?course_record=%s'>记录</a>"%(obj.pk))
改一下全局的:
# if filter_field in self.list_filter:
if filter_field !="page":
filter_condition.children.append((filter_field, val))
2. record,score显示;get_field_display
放到全局:
if field_obj.choices:
val = getattr(obj,"get_"+field+"_display")
else:
val = getattr(obj, field)
3. 批量处理迟到
queryset.update(record="late")
-----------------------
def record(self, obj=None, header=False):
if header:
return "学习记录"
return mark_safe("<a href='/stark/crm/studyrecord/?course_record=%s'>记录</a>"%(obj.pk))
list_display = ["class_obj", 'day_num', "teacher", record, record_score ]
---------------------
class StudyRecordConfig(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,StudyRecordConfig)
五、录入成绩

知识点
1. mark_safe
mark_safe("<a href='record_score/%s'>录入成绩</a>"%obj.pk)
2. 新增url
def extra_url(self):
temp = []
temp.append(url(r'^record_score/(\d+)', self.score))
return temp
3. form表单提交数据
request.post:
'''
<QueryDict: {'csrfmiddlewaretoken': ['muIrf7pwbxIueSJcKADRlZEGVbzzRZOaiGVkBV8DGYC2V9gmxZtyZgujddFtTojk'],
'score_33': ['100'], 'homework_note_33': ['很好'],
'score_34': ['85'], 'homework_note_34': ['棒'],
'score_35': ['60'], 'homework_note_35': ['None']}>
'''
4. 处理数据( field, pk = key.rsplit('_', 1) )
data = {} # data={"33":{"score":100,"homework_note":'xxx'},}
for key,value in request.POST.items():
if key == "csrfmiddlewaretoken":continue
field, pk = key.rsplit('_', 1)
if pk in data:
data[pk][field] = value
else:
data[pk] = {field:value}
print("data-->",data)
'''
{'33': {'score': '100', 'homework_note': '很好'},
'34': {'score': '85', 'homework_note': '棒'},
'35': {'score': '60', 'homework_note': 'None'}}
'''
5. 更新数据
for pk,update_data in data.items():
StudyRecord.objects.filter(pk=pk).update(**update_data)
6. 跳转当前页面
return redirect(request.path)
7. get请求
study_record_list = StudyRecord.objects.filter(course_record__id=course_record_id)
score_choices = StudyRecord.score_choices
return render(request,'score.html',locals())
def score(self,request, course_record_id):
if request.method == "POST":
print('post::::', request.POST)
'''
<QueryDict: {'csrfmiddlewaretoken': ['muIrf7pwbxIueSJcKADRlZEGVbzzRZOaiGVkBV8DGYC2V9gmxZtyZgujddFtTojk'],
'score_33': ['100'], 'homework_note_33': ['很好'],
'score_34': ['85'], 'homework_note_34': ['棒'],
'score_35': ['60'], 'homework_note_35': ['None']}>
'''
data = {} # data={"33":{"score":100,"homework_note":'xxx'},}
for key,value in request.POST.items():
if key == "csrfmiddlewaretoken":continue
field, pk = key.rsplit('_', 1) if pk in data:
data[pk][field] = value
else:
data[pk] = {field:value} print("data-->",data)
'''
{'33': {'score': '90', 'homework_note': '很好'},
'34': {'score': '80', 'homework_note': '帮帮哒'},
'35': {'score': '50', 'homework_note': '没问题'}} '''
for pk,update_data in data.items():
StudyRecord.objects.filter(pk=pk).update(**update_data) return redirect(request.path) else:
study_record_list = StudyRecord.objects.filter(course_record__id=course_record_id)
score_choices = StudyRecord.score_choices
return render(request,'score.html',locals()) def extra_url(self):
temp = []
temp.append(url(r'^record_score/(\d+)', self.score))
return temp def record_score(self, obj=None, header=False):
if header:
return "录入成绩"
return mark_safe("<a href='record_score/%s'>录入成绩</a>"%obj.pk) list_display = ["class_obj", 'day_num', "teacher", record, record_score ]
score.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="">
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
</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.get_record_display }}</td>
<td style="width: 100px; padding: 5px 10px;">
<select name="score_{{ study_record.pk }}" id="" class="form-control">
{% for item in score_choices %}
{% if study_record.score == item.0 %}
<option selected value="{{ item.0 }}">{{ item.1 }}</option>
{% else %}
<option value="{{ item.0 }}">{{ item.1 }}</option>
{% endif %}
{% endfor %}
</select> </td>
<td>
<textarea name="homework_note_{{ study_record.pk }}" id="" cols="30" rows="3" 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>
六、查看成绩 - highcharts

知识点
1. 查看成绩
mark_safe("<a href='/stark/crm/student/score_view/%s'>查看成绩</a>"%obj.pk)
2. 扩展url
temp.append(url(r'^score_view/(\d+)', self.score_view))
3. get
student = Student.objects.filter(pk=sid).first()
class_list = student.class_list.all()
4. request.is_ajax
sid = request.GET.get('sid')
cid = request.GET.get('cid')
5. 跨表查询
准备数据:[['day94', 85], ['day95', 85], ['day96', 60]]
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]) print('----',data_list) # [['day94', 85], ['day95', 85], ['day96', 60]]
6. JsonResponse()
返回JsonResponse,非字典需要加上 safe = False
return JsonResponse(data_list,safe=False)
7. 前端
注意:cid sid 用法; ajax 显示 highcharts 柱状图
<a class="check_chart" cid="{{ cls.pk }}" sid="{{ student.pk }}">查看成绩</a>
<div id="container" style="width: 600px; height: 400px;"></div> <script type="text/javascript">
$('.check_chart').click(function () {
$.ajax({
url:"",
type:"get",
data:{
cid:$(this).attr('cid'),
sid:$(this).attr('sid')
},
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:.1f} </b>'
},
series: [{
name: '总人口',
data: data,
dataLabels: {
enabled: true,
rotation: -90,
color: '#FFFFFF',
align: 'right',
format: '{point.y:.1f}', // :.1f 为保留 1 位小数
y: 10
}
}]
});
}
}) }); </script>
from django.http import JsonResponse
class StudentConfig(ModelStark):
def score_view(self,request,sid):
if request.is_ajax():
# print(request.GET)
cid = request.GET.get('cid')
sid = request.GET.get('sid') # 跨表查
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])
# # [['day94', 85], ['day95', 85], ['day96', -1]]
return JsonResponse(data_list,safe=False) else:
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='score_view/%s'>查看成绩</a>"%obj.pk) list_display = ['customer','class_list',score_show]
list_display_links = ['customer'] site.register(Student,StudentConfig)
crm/stark.py
# -*- coding:utf-8 -*- from .models import *
from stark.service.stark import site, ModelStark
from django.utils.safestring import mark_safe
from django.conf.urls import url
from django.shortcuts import HttpResponse,reverse,redirect,render class DepartmentConfig(ModelStark):
list_display = ['title', 'code'] site.register(Department, DepartmentConfig) class UserInfoConfig(ModelStark):
list_display = ["name", 'email', 'depart'] site.register(UserInfo, UserInfoConfig) class ClassListConfig(ModelStark):
def display_classname(self,obj=None,header=False):
if header:
return "班级名称"
return "%s(%s)"%(obj.course.name, obj.semester) list_display = [display_classname, 'tutor', 'teachers'] site.register(ClassList, ClassListConfig) class CustomerConfig(ModelStark):
def display_course(self, obj=None, header=False):
if header:
return "咨询课程" temp = []
for course in obj.course.all():
temp.append("<a href='/stark/crm/customer/cancel_course/%s/%s' style='border:1px solid #369; padding:3px 6px;'><span>%s</span></a> "%(obj.pk,course.pk,course.name)) return mark_safe("".join(temp)) def cancel_course(self, request, customer_id, course_id):
customer_obj = Customer.objects.filter(pk=customer_id).first()
customer_obj.course.remove(course_id)
return redirect(self.get_list_url()) # 重定向到当前表得查看页面 def extra_url(self):
temp = []
temp.append(url(r'^cancel_course/(\d+)/(\d+)', self.cancel_course))
return temp list_display = ["name", "gender",display_course ,"consultant"] site.register(Customer, CustomerConfig) class ConsultRecordConfig(ModelStark):
list_display = ["customer", 'consultant','date','note'] site.register(ConsultRecord, ConsultRecordConfig) from django.http import JsonResponse
class StudentConfig(ModelStark):
def score_view(self,request,sid):
if request.is_ajax():
# print(request.GET)
cid = request.GET.get('cid')
sid = request.GET.get('sid') # 跨表查
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])
# # [['day94', 85], ['day95', 85], ['day96', -1]]
return JsonResponse(data_list,safe=False) else:
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='score_view/%s'>查看成绩</a>"%obj.pk) list_display = ['customer','class_list',score_show]
list_display_links = ['customer'] site.register(Student,StudentConfig) class CourseRecordConfig(ModelStark): def score(self,request, course_record_id):
if request.method == "POST":
print('post::::', request.POST)
"""
<QueryDict: {'csrfmiddlewaretoken': ['muIrf7pwbxIueSJcKADRlZEGVbzzRZOaiGVkBV8DGYC2V9gmxZtyZgujddFtTojk'],
'score_33': ['100'], 'homework_note_33': ['很好'],
'score_34': ['85'], 'homework_note_34': ['棒'],
'score_35': ['60'], 'homework_note_35': ['None']}>
"""
data = {} # data={"33":{"score":100,"homework_note":'xxx'},}
for key,value in request.POST.items():
if key == "csrfmiddlewaretoken":continue
field, pk = key.rsplit('_', 1) if pk in data:
data[pk][field] = value
else:
data[pk] = {field:value} print("data-->",data)
"""
{'33': {'score': '90', 'homework_note': '很好'},
'34': {'score': '80', 'homework_note': '帮帮哒'},
'35': {'score': '50', 'homework_note': '没问题'}} """
for pk,update_data in data.items():
StudyRecord.objects.filter(pk=pk).update(**update_data) return redirect(request.path) else:
study_record_list = StudyRecord.objects.filter(course_record__id=course_record_id)
score_choices = StudyRecord.score_choices
return render(request,'score.html',locals()) def extra_url(self):
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)) def record_score(self, obj=None, header=False):
if header:
return "录入成绩"
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):
# print('queryset:--》',queryset)
temp = []
for course_record in queryset:
# 与course_record 关联得班级对应得学生
students_list = Student.objects.filter(class_list__id = course_record.class_obj.pk)
for student in students_list:
student_obj = StudyRecord(course_record=course_record,student=student)
temp.append(student_obj) StudyRecord.objects.bulk_create(temp) actions = [patch_studyrecord]
patch_studyrecord.short_description = "批量生成学习记录" site.register(CourseRecord,CourseRecordConfig) class StudyRecordConfig(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,StudyRecordConfig) site.register(Course)
site.register(School)
stark.py
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>
<script src="/static/chart/highcharts.js"></script>
</head>
<body>
<h3>查看{{ student }}成绩</h3> <div class="container">
<div class="row">
<div class="col-md-9">
<form action="">
<table class="table-bordered table table-striped">
<thead>
<tr>
<th>班级</th>
<th>班主任</th>
<th>任课老师</th>
<th>课程成绩</th>
</tr>
</thead>
<tbody>
{% for cls in class_list %}
<tr>
<td>{{ cls }}</td>
<td>{{ cls.tutor }}</td>
<td>
{% for teacher in cls.teachers.all %}
<span>{{ teacher }}</span>,
{% endfor %} </td>
<td>
<a class="check_chart" cid="{{ cls.pk }}" sid="{{ student.pk }}">查看成绩</a>
</td>
</tr>
{% endfor %} </tbody>
</table>
</form>
</div>
</div> </div> <div id="container" style="width: 600px; height: 400px;"></div> <script type="text/javascript">
$('.check_chart').click(function () {
$.ajax({
url:"",
type:"get",
data:{
cid:$(this).attr('cid'),
sid:$(this).attr('sid')
},
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:.1f} </b>'
},
series: [{
name: '总人口',
data: data,
dataLabels: {
enabled: true,
rotation: -90,
color: '#FFFFFF',
align: 'right',
format: '{point.y:.1f}', // :.1f 为保留 1 位小数
y: 10
}
}]
});
}
}) }); </script> </body>
</html>
score_view.html
CRM - 讲师与学生的更多相关文章
- 2 CRM 讲师与学生,highcharts应用
一.讲师与学生简介 1 初始化 course_record,studyrecord, 2 考勤 3 录入成绩 4 显示成绩 ajax 查询 5 上传作业(os模块) 6 下载作业 二. 初始化 ,st ...
- CRM——讲师与学生
一.课程记录和学习记录 1.初始化 course_record, study_record.2.学习记录3.录入成绩4.显示成绩 ajax 查询 柱状图展示成绩 highcharts 5.上传作业(o ...
- Django项目:CRM(客户关系管理系统)--79--69PerfectCRM实现CRM业务流程(bpm)学生讲师分页
# student_views.py # ————————60PerfectCRM实现CRM学生上课记录———————— from django.shortcuts import render #页面 ...
- Django项目:CRM(客户关系管理系统)--73--63PerfectCRM实现CRM讲师下载作业
# teacher_urls.py # ————————62PerfectCRM实现CRM讲师讲课记录———————— from django.conf.urls import url from bp ...
- Django项目:CRM(客户关系管理系统)--72--62PerfectCRM实现CRM讲师讲课记录
#urls.py """PerfectCRM URL Configuration The `urlpatterns` list routes URLs to views. ...
- Django - 学习目录
Django 基础 web应用/http协议/web框架 Django简介 Django - 路由层(URLconf) Django - 视图层 Django - 模板层 Django - 模型层 - ...
- python全栈开发之路
一.Python基础 python简介 python数据类型(数字\字符串\列表) python数据类型(元组\字典) python数据类型(集合) python占位符%s,%d,%r,%f prin ...
- CRM系统(第二部分)
阅读目录 一.讲师与学生简介 二. 初始化 ,studyrecord, 三.初始化 course_record:批量生成学习记录 四. 考勤 url跳转 五.录入成绩 六.highcharts表 ...
- 10.23 crm(3)
2018-10-23 20:34:30 继续增加新的功能!在代码注释里面有! 越努力,越幸运!永远不要高估自己! 还有明天再加上rbca权限管理系统就完美了! 然后crm做完,再过几天不挂针一切好了也 ...
随机推荐
- vector deque list
vector ,deque 和 list 顺序性容器: 向量 vector : 是一个线性顺序结构.相当于数组,但其大小可以不预先指定,并且自动扩展.它可以像数组一样被操作,由于它的特性我们完全可 ...
- ms-SQL 递归调用
----递归函数-------------------------------------------------------------------------- create function d ...
- 性能测试指标的理解--cpu和load
第一次做性能测试,按照操作文档磕磕碰碰的完成了,并且拿到了结果,看到一堆的指标和数据,还是傻眼了,不知道各个指标是什么意思了. 咨询了大牛和度娘,消化理解了一下,不知道是不是正确的. CPU使用率: ...
- 【scrapy】相关
http://www.cnblogs.com/mophee/archive/2009/03/12/1409562.html css选择器中的空格 http://www.crummy.com/softw ...
- 【算法】CRF
http://www.open-open.com/doc/view/7e983c0bf1594849bcd088dc212098c4 http://wenku.baidu.com/link?url=c ...
- Resharper 安装以及破解
首先进行软件安装 安装后 解压下载好的 文件 会得到如下: 打开序列号 会看到 然后 复制 %LocalAppData%\\JetBrains 路径 会得到进入当前JetBrains 文件夹 然后搜 ...
- Unity教程之-基于行为树与状态机的游戏AI
AI.我们的第一印象可能是机器人,现在主要说在游戏中的应用.关于AI的相关文章我们在前面也提到过,详细请戳这现代的计算机游戏中已经大量融入了AI元素,平时我们进行游戏时产生的交互都是由AI来完成的.比 ...
- OpenCV学习:图像的载入和显示
一.使用IplImage结构读取并显示图像文件: 运行结果: 二.使用Mat类读取并显示图像文件: 使用 Mat 类,内存管理变得简单,不再像使用 IplImage 那样需要自己申请和释放内存,而且一 ...
- Extjs不错的博客
http://www.cnblogs.com/fangsui/category/372751.html http://www.cnblogs.com/WangJinYang/tag/EXT.NET/ ...
- docker学习-docker镜像
docker就是一系列文件,