所有演示均基于Django2.0
阅读此篇文章你可以:
- 了解Django中aggregate和annotate函数的使用方法
- 获取一个Django+Echarts绘制柱状图的完整示例
需求说明
一张会议记录表,里边有一个字段存放会议举行的地点,例如北京、上海、洛阳等等,需要取举行会议最多的前20个地点绘制成柱状图展示,项目为前后端分离的架构
需求分析
看了需求主要有三个关键点:
1.前后端分离:前端只负责页面渲染,后端提供API负责数据输出
2.需要绘制成柱状图:绘制图表的第三方插件有很多,我们这里就选择百度开源的echarts,简单好用且功能强大
3.取举行会议最多的前20个地点:了解一点SQL知识的话就知道需要先要对地点字段进行group by,然后order by desc倒序,最后limit取前20
那么在Django中应该如何group by,并在group by之后order by排序,最后limit呢?这里我们介绍django的两个函数aggregate
和annotate
aggregate
aggregate聚合函数,用于对QuerySet整个对象结果的汇总,例如获取员工总数(COUNT),平均(AVG)年龄,最大(MAX)年龄,最小(MIN)年龄,销售总额(SUM)等,输出的结果是一个字典
我们有一个model如下:
class Employee(models.Model):
name = models.CharField(max_length=32, verbose_name='姓名')
age = models.IntegerField(verbose_name='年龄')
salary = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='薪资')
想要获取员工的工资总额,我们可以这样写
>>> from django.db.models import Sum
>>> Employee.objects.aggregate(Sum('salary'))
{'salary__sum': Decimal('5000.00')}
想要同时获取员工的平均年龄、最大年龄和最小年龄,我们可以这样写
>>> from django.db.models import Avg, Max, Min
>>> Employee.objects.aggregate(Avg('age'), Max('age'), Min('age'))
{'age__avg': 23.333333333333332, 'age__max': 30, 'age__min': 18}
annotate
annotate函数区别于aggregate函数的一个最重要的地方是annotate函数输出的结果是一个QuerySet对象,这个非常重要,aggregate函数最后输出的结果是个字典,也就不能再在字典的基础上进行QuerySet操作了,而annotate函数执行完成后输出QuerySet对象可以继续调用Django内置的filter、order_by等函数来完成更加复杂的查询计算操作
用到annotate函数的逻辑往往比较复杂,Django非常人性化的提供了query方法,方便查看annotate生成的SQL语句帮助我们确定执行过程
以上边的实际需求为例,model如下:
class EventInfo(models.Model):
event_location = models.CharField(max_length=30)
class Meta:
db_table = "app_event_info"
我们需要先对地点event_location进行group by:
>>> _t = EventInfo.objects.values_list('event_location').annotate(Count('id'))
# values_list可以获取evnet_location的元组列表。
# values_list方法加个参数flat=True可以获取event_location的值列表。
group by之后我们就需要order by排序了,如果我们不知道order by的字段,我们可以通过query先查看group by生成的SQL语句
>>> print(_t.query)
SELECT "app_event_info"."event_location", COUNT("app_event_info"."id") AS "id__count" FROM "app_event_info" GROUP BY "app_event_info"."event_location"
这个时候可以看到实际上输出的结果有一个叫id__count
的字段表示地点的总数,那么我们就可以接着对地点总数进行排序了,因为是要倒叙,需要在字段名id__count
前边加上-
号来表示倒序
>>> _x = _t.order_by('-id__count')
>>>
>>> print(_x.query)
SELECT "app_event_info"."event_location", COUNT("app_event_info"."id") AS "id__count" FROM "app_event_info" GROUP BY "app_event_info"."event_location" ORDER BY "id__count" DESC
最后limit取前二十,Django中limit可以直接通过QuerySet结果后加python的数组切片语法来实现,就像[0:20](其中0可以省略)相当于limit 20一样,[10:20]意思为取第10到第20条数据
>>> _y = _x[:20]
>>>
>>> print(_y.query)
SELECT "app_event_info"."event_location", COUNT("app_event_info"."id") AS "id__count" FROM "app_event_info" GROUP BY "app_event_info"."event_location" ORDER BY "id__count" DESC LIMIT 20
上边的每一步我们都通过query打印了SQL,确定是我们想要的结果了。需求分析清楚,所有的关键点我们也都知道怎么处理了,那么接下来实现就水到渠成了。
实现代码
URL如下:
from django.urls import path
from django.views.generic.base import TemplateView
from .views import echarts_data
urlpatterns = [
path('echarts/', TemplateView.as_view(template_name='echarts.html'), name='echarts-url'),
path('api/echarts/', echarts_data, name='api-echarts')
]
因为是前后端分离的,所以我这里用了两个urlecharts
和api/echarts
echarts
为前台访问地址,对应下边的html代码,通过ajax方式调用后端接口,所以这里直接用了TemplateView,不需要再写额外的view代码
api/echarts
为后端API的地址,对应下边的view代码,为前台提供数据接口
前端HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ops-coffee</title>
<!-- 引入 echarts.js -->
<script src="/static/js/jquery.min.js"></script>
<script src="/static/js/echarts/echarts.common.min.js"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="height:400px;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
$.ajax({
type: "get",
url: "/api/echarts",
dataType: "json",
success: function (data) {
// 指定图表的配置项和数据
var option = {
title: {
left: 'center',
text: 'ops-coffee 运维咖啡吧'
},
tooltip: {},
xAxis: {
data: data.key
},
yAxis: {},
series: [{
name: '数量',
type: 'bar',
data: data.value
}]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
},
error: function () {
alert('Error: ajax 请求出错!')
}
});
</script>
</body>
</html>
实例比较简单,抄的echarts官方示例,这里会看到echarts渲染图形实际上只需要X轴和Y轴两个数据变量,且都为list列表类型
后端VIEW:
from django.http import JsonResponse
from django.db.models import Count
from .models import EventInfo
def echarts_data(request):
_x = EventInfo.objects.values_list('event_location').annotate(Count('id')).order_by('-id__count')[:20]
jsondata = {
"key": [i[0] for i in _x],
"value": [i[1] for i in _x]
}
return JsonResponse(jsondata)
最核心的那行group by + order by + limit的ORM拼接,我们上边已经详细的介绍过了,那么这里只需要在输出的结果中单独的把城市跟数量转成两个列表对应echarts里边需要的X轴Y轴数据就可以了
最后访问url:https://ops-coffee.cn/echarts 可以看到我们想要的结果
![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABS4AAAGQCAYAAACgWf7EAAAgAElEQVR4nO3dDbxdVX0n/E1LTZRGE1Ay0LQxSVWggjZJsRbajk3M0DYwY9TKQC2OFu3jWIWMY994BC1q9KERSNunxVpr49haMI4xLQ6S2mYSrTGJCApqNUGN0uBLEuJLVCiPv/3Mut335L7lJjdn3Zvv9/M5n9x79rkna++zzz57/85/rXXCw9/XAAAAAABU5Af63QAAAAAAgF6CSwAAAACgOoJLAAAAAKA6gksAAAAAoDqCSwAAAACgOoJLAAAAAKA6gksAAAAAoDqCSwAAAACgOoJLAAAAAKA6gksAAAAAoDqCSwAAAACgOoJLAAAAAKA6gksAAAAAoDo/eM339bsRAAAcHd/97neb7du3N7feemuzY8eO5jGPeUxz8sknt8sefvjh5t57723+7u/+rvnwhz/cfOMb32h+9Ed/tPmBH5j477Lzf99zzz3N61//+uaMM85oZs6c2d5/8ODBth35d6TbD/7gD7a34pZbbmluvPHG5od/+IebH/uxH2tOOOGE9v94y1ve0rz3ve9t13v//v3Nm970puaUU05pTjvttDG18/bbb29e85rXNE94whOaU0899YjXe9euXc2v/dqvNX/1V3/VPP3pT29/v/DCC5svfOELzc/8zM80J5544oh//9BDD7Xb59vf/vaI2ydGey4AgMnG2Q0AwBTx1a9+tcl30v/0T/80cF/CtwULFrQB2J//+Z83b33rW5sHH3ywXXbBBRc0P/3TPz0oEJwoX/ziF5tXv/rVbXD66Ec/uvmt3/qt5lGPelRz2223Na997WtH/fubbrqpWbhwYfvzt771rTZ4veOOO5rnPOc5A8Hrvn372nW/8847m2XLljX33Xdfs2nTpubAgQPN6173uoEAN7I9vvnNbzb/+q//OnDfSSed1D73Jz/5yTYALhKIJjzM3xTZZglN83/+8z//86C2PuIRj2jOOuus9t+xSls+9alPDfo/8vx5jiuvvLJdl5Fk21500UVj/v8AACYDwSUAwBSQcG39+vUDoWUCyYRnqTaMhHFr165tQ8tUWf7CL/xCu+xYVFtGqiJ/4zd+o7nqqquav/3bv23mzJnTvPCFLxzXc332s59tPvrRjzaLFy9uzj333IH7E45m2ROf+MT2lmD0gx/8YFvpmfu7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)
整个Demo示例介绍完成。
![长按关注公众号查看更多原创文章](https://user-gold-cdn.xitu.io/2018/11/19/16729b049cde8b7a?w=430&h=476&f=jpeg&s=38786)
如果你觉得文章对你有帮助,请转发分享给更多的人。如果你觉得读的不尽兴,推荐阅读以下文章: