最近在使用Django实现图表化功能时遇到了无法在后台生成图表的功能,在此记录下实现过程。
步骤如下:
1、在所要展示的类的model新建一个类,LZ的代码如下:
class ViewsByDayModel(ViewsByDay): # 父类为要展示的model类
class Meta:
proxy = True # 使用代理
verbose_name = '每日浏览次数统计'
verbose_name_plural = verbose_name
2、在admin.py里注册该类,重写changelist_view,并获取数据后台数据。
class ViewsByDayAdmin(ImportExportModelAdmin):
list_filter = (
'date',
)
change_list_template = 'admin/admin_test.html'
def changelist_view(self, request, extra_context=None):
response = super().changelist_view(
request,
extra_context=extra_context
)
try:
qs = response.context_data['cl'].queryset
except (AttributeError, KeyError):
return response
metrics = {
'days': Sum('date'), # date是model累的字段
'views_count': Sum('views_count'), # views_count是model累的字段
'ip_count': Sum('ip_count'), # ip_count是model累的字段
}
response.context_data['date'] = list(
qs
.values('date')
.annotate(**metrics)
)
return response
3、编写前台页面获取数据,加载echarts插件,做出图表。代码如下。
{% extends 'admin/change_list.html' %}
{% load staticfiles %}
{% block content_title %}
<!-- ECharts单文件引入 -->
<script src="{% static 'js/echarts.min.js' %}"></script>
<script src="http://echarts.baidu.com/build/dist/echarts.js"></script>
{% endblock %}
{% block result_list %}
<a href="{% url 'viewsCount:views_export' %}" style="font-weight: bold; font-size: 20px;">导出成xls</a>
<div id="mains" style="height:400px; width: 1000px;"></div>
<script>
let myChart = echarts.init(document.getElementById('mains'));
let data1 = [];
let data2 = [];
let day = [];
{% for i in date %}
data1.push({{ i.views_count }});
data2.push({{ i.ip_count }});
day.push({{ i.days }});
{% endfor %}
myChart.setOption({
toolbox: {
show: true,
feature: {
mark: {show: true},
dataView: {show: true, readOnly: false},
magicType: {show: true, type: ['line', 'bar']},
restore: {show: true},
saveAsImage: {show: true}
}
},
calculable: true,
title: {
text: '网站每日浏览次数'
},
tooltip: {
trigger: 'axis',
},
legend: {
data: ['访问次数', 'ip数量']
},
xAxis: [
{
type: 'category',
data: day
}
],
yAxis: [
{
type: 'value',
}
],
series: [
{
name: '访问次数',
type: 'bar',
data: data1,
markPoint: [
{type: 'max', name: '最大值'},
{type: 'min', name: '最小值'}
]
},
{
name: 'ip数量',
type: 'bar',
data: data2,
markPoint: [
{type: 'max', name: '最大值'},
{type: 'min', name: '最小值'}
]
},
]
});
</script>
{% endblock %}
效果预览:
ps:页面中的倒叙日期,可以在
response.context_data['date'] = list(
qs
.values('date')
.annotate(**metrics)
)
下添加语句 .order_by('date')实现正序输出。