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)
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>