知识点1
我们要实现一个这样的功能,在学生表中,可以查看每个学生的报名的班级的所有的成绩,就是下图的效果
1、首先我们需要在学生表中自定义一列,这一列的内容就是一个a标签,指向另外一个页面,而我们在另外一个页面显示显示这个学生的所有的成绩
新添加一列的函数如下
def score_show_url(self,obj=None,header=False): if header: return "查看成绩" else: temp = "<a href='/stark/crm/student/{sid}/'>查看个人成绩</a>".format(sid=obj.id) return mark_safe(temp)
2、由于我们这里新增了一个url,所以需要为这个url设计一个新的视图函数
首先为这个url设计对应的视图函数的名称
def extra_url(self): temp = [] temp_url = url(r'(?P<sid>\d+)/',self.show_score) temp.append(temp_url) return temp
然后我们设计具体的视图函数,这个视图函数是完整的视图函数,我们先不用管,只需要知道这个流程就可以了
def show_score(self,request,sid): stu_obj = models.Student.objects.get(id=sid) # 拿到学生对象 stu_class_list = stu_obj.class_list.all() if request.is_ajax(): sid = request.GET.get("sid") cid = request.GET.get("cid") # 拿到这个学生的所报的班级的queryset对象 stu_record_dict = {} for record in stu_class_list: stu_record_dict[record.id] = record.courserecord_set.all() data_list = [] for k,v in stu_record_dict.items(): # print(k,cid,type(k),type(cid)) if k == int(cid): for m in v: print(stu_obj,m,m.studyrecord_set.filter(student = stu_obj)[0].get_score_display()) temp = [str(m),m.studyrecord_set.filter(student = stu_obj)[0].score] data_list.append(temp) import json print(data_list) from django.http import JsonResponse return JsonResponse(data_list,safe=False) return render(request,"score_view.html",locals())
3、首先这个视图函数接收一个参数,这个参数就是学生的id,我们通过拿到这个学生的id就可以获取这个学生的所有的成绩了
4、然后返回一个页面
5、然后我们在下这个页面的html代码
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/html"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/css/bootstrap.min.css"> </head> <body> <h3>查看<b>{{ stu_obj.username }}</b>成绩</h3> <div class="container"> <div class="row"> <div class="col-md-9"> <form 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 cls in stu_class_list %} <tr> <td>{{ cls }}</td> <td>{{ cls.tutor }}</td> <td>{% for t in cls.teachers.all %} {% if forloop.last %} {{t.name}} {% else %} {{ t.name }} & {% endif %} {% endfor %} </td> <td><a class="view_score" cid={{ cls.id }} href="#">查看成绩</a></td> </tr> {% endfor %} </tbody> </table> </form> </div> </div> </div> </body>
下面我们分解一下html的代码,其实就是一个table标签,表头的代码
<table class="table table-bordered table-striped"> <thead> <tr> <th>班级</th> <th>班主任</th> <th>任课老师</th> <th>查看成绩</th> </tr> </thead>
表身体的代码
<tbody> {% for cls in stu_class_list %} <tr> <td>{{ cls }}</td> <td>{{ cls.tutor }}</td> <td>{% for t in cls.teachers.all %} {% if forloop.last %} {{t.name}} {% else %} {{ t.name }} & {% endif %} {% endfor %} </td> <td><a class="view_score" cid={{ cls.id }} href="#">查看成绩</a></td> </tr> {% endfor %} </tbody>
这里注意一下,判断是否为for循环的最后一个
最后我们看下前端页面的效果
首先是在学生表中新增了一列数据
然后我们点击任意一个a标签,进入这个用户的查看成绩的页面
重点是这里,查看成绩的这个a标签
我们要为这个a标签绑定一个单击的事件,点击这个a标签,发送一个ajax的事件
首先我们看下ajax发送给后端的数据是什么,将学生的id和班级的id发送过去了,因为一个学生可以 报多个班级,我们是这里为每个学生的每个班级设计了a标签的按钮
$.ajax( { url: "", data: { sid: "{{ stu_obj.id }}", cid: $(this).attr("cid"), }, type: "get",
然后我们在看下视图函数,如何通过班级的id和学生的id拿到所要的成绩信息
if request.is_ajax(): sid = request.GET.get("sid") cid = request.GET.get("cid") # 拿到这个学生的所报的班级的queryset对象 stu_record_dict = {} for record in stu_class_list: stu_record_dict[record.id] = record.courserecord_set.all() data_list = [] for k,v in stu_record_dict.items(): # print(k,cid,type(k),type(cid)) if k == int(cid): for m in v: print(stu_obj,m,m.studyrecord_set.filter(student = stu_obj)[0].get_score_display()) temp = [str(m),m.studyrecord_set.filter(student = stu_obj)[0].score] data_list.append(temp) import json print(data_list) from django.http import JsonResponse return JsonResponse(data_list,safe=False)
首先这里有一个新的知识点,就是判断这次的请求是否为ajax的请求
这里我们点击查看成绩的按钮,我们用了一个highcharts的组件,这个组件就要接受一个列表套列表的数据结构,上面我们就组件了一个这样的结构
然后引入highcharts的组件的js文件
<script src="/static/jq/jquery-3.3.1.js"></script> <script src="/static/highcharts/code/highcharts.js"></script>
下面这段代码是highcharts中的代码,我们只需要按照他的要求把数据传递过来就可以了
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: [#} {# ['上海', 24.25],#} {# ['卡拉奇', 23.50],#} {##} {# ],#} data: data, dataLabels: { enabled: true, rotation: -90, color: '#FFFFFF', align: 'right', format: '{point.y:.1f}', // :.1f 为保留 1 位小数 y: 10 } }] }); } } ) })
页面的的效果如下