Python Django+SQL+Pandas+Pyecharts自建在线数据分析平台(三)
文章来源:Python Django+SQL+Pandas+Pyecharts自建在线数据分析平台(一)
作者:ccpic
感谢:感谢作者 ccpic 分享的优质内容,本网页主要用于学习知识的存档备份,欢迎点击原网页支持作者。
本篇是系列文章的第三篇:
(一)需求分析&技术实现
(二)初步搭建Django环境
(四)SQL+Pandas初步处理数据
(五)前端表单交互
(六)Ajax异步传参与加载
(七)前端数据格式的处理
(八)DataTables接管前端表格
(九)Pyecharts实现交互图表
(十)静态图表的展示
(十一)“导出数据至Excel”功能
(十二)添加和配置缓存
(十三)用户登录系统
(十四)部署Django至生产环境
在上一章初步打通前后端通信后,接下来的方向无疑是两端的分别扩展和完善。本章先来看一下前端页面布局和Django模板的问题。
本例的页面布局没有任何标新立异的地方,主页面采用header-body-footer的上中下布局,header和footer是几乎静态的,body则是动态的。body在部分功能下是一块整体,在核心的分析功能下分成filter-display的左右布局。filter承担向后端提交input的角色,display则展示后端根据input返回的response。
(在更进阶的情况下,负责分析的body页面还可以进一步分为filter-display-setting的左中右布局)。
我们构思的整个布局如下图所示:
根据此设计,我们需要搭建相应的Django模板架构,并充分利用其模板继承特性,其中主要需要理解base-extend机制以及block和include两个主要的模板语句。
在这里我省略了讲解Django模板加载器的部分,其实这一部分也是有讲究的,尤其是对于多个app的更大型的工程。
按照官网推荐的结构,先在本例的chpa_data新建文件夹templates,再在templates内新建和app同名的文件夹chpa_data,再在其内新建Django的html模板文件。
首先,创建一个base.html代表这个模板的基础结构(可以称之为基础模板或父模板):
<!-- 载入静态文件 更早版本可能会用load staticfiles --> |
在header部分我们引用了这个工程需要的静态文件,所有继承base的页面就可以不再引用了。这里需要在datasite下的settings.py加一条设置以识别静态文件夹的位置:
STATIC_URL = '/static/' # 静态文件夹相对于工程根目录的相对位置 |
而base.html代码中最重要的是需要理解 {% include %}和{% block %}{% endblock %}的区别。{% include %}是直接引用一个相对独立的代码块,{% block %}{% endblock %}则是给所有extend base.html的子模板预留可以复写的位置,在子模板要有对应的block。从另一个角度说,子模版block之间的内容可以覆盖父模板中的相同block。
这里的概念有些容易混淆,其实这么理解就可以了,当代码块是通用的相对静态的时候,使用include语句直接引用;而当可能有多个子模板多次继承重写同一部分时,预留block。或者简单说,include是多对一的关系(但因为继承,大部分实际情况下是一对一),而block是一对多的关系。
所以对于我们的app,header和footer是相对静态的,不会出现多个不同的header和footer。我们在templates文件夹下创建header.html和footer.html,只是为了方便单独管理。使用semantic ui的语句简单写一点header和footer。
header.html:
<div class="ui large top fixed inverted menu"> |
这里第一次出现Django特色的url tag,{%url”chpa:index”%}的结构实际是对应chpa_data的urls.py文件里的{% url “app_name:view_name” %}。一定注意这里是urls.py里为urls们命名的app_name参数,而不是实际上这个工程里app的name。所以这里是chpa而不是chpa_data。
footer.html:
<div class="ui inverted vertical footer segment"> |
注意header和footer的代码就是这么短,是不需要extends语句的。
而base里预留的{% block body %}{% endblock body %}部分是可以复用的,我们可以测试两个页面分别继承的情况,这两个页面的开头语句都是:
{% extends "chpa_data/base.html" %} |
我们可以有一个静态的项目首页index.html,他的内容是极其简单的,以后可以是个含有导航信息或说明文字的静态首页,这次我们先预留一个{{ data }} tag准备接受测试时后台传来的数据:
<!-- extends表明此页面继承自 base.html 文件 --> |
再创建一个相对复杂的analysis.html,根据本章开头的设计,这个页面应该是左边是filter,而右边是display。这里涉及到进一步嵌套的模板继承,filter一般不会变,所以直接include,而display有可能有多个子模板再复用,继续预留block位置:
<!-- extends表明此页面继承自 base.html 文件 --> |
最后再创建filter.html文件,可以暂时为空。
**display.html文件,注意这里的第一行不是extends base.html而是extends analysis.html。**我们再和index.html一样预留 {{ data }} tag准备测试:
{% extends "chpa_data/analysis.html" %} |
此时Django模板架构完毕,再确认一次项目结构:
我们可以修改上一章中views.py的index方法做个测试,因为在模板里预留了{{ data }}tag,我们不希望再传一个整体的HttpResponse了,而是希望传一个包含data键值的context。修改代码如下:
from django.shortcuts import render |
可以看到首页已经发生了改变。

如果render到display模板会怎样呢?
return render(request, 'chpa_data/display.html', context) |

很明显我们为分析功能设计的filter-display左右布局也生效了。
本章是反馈出问题最多的地方,特再次总结一遍容易踩坑的要点:
- 项目结构建议完全按照截图。在教程的早期版本我曾经把模板html文件直接放在templates文件夹下,后来一些朋友反馈Django高级版本会报错,所以请不要这么做。
- 按照截图推荐的结构的情况下,所有要引用模板path的extends, include和render等语句,路径一定都是’chpa_data/xxx.html’而不是’xxx.html’。这是因为加载模板是根据绝对位置(templates文件夹)而不是相对位置。
- 只有预留block的子模板要在头部加入对应的extends语句,include的子模版不需要加。
下一篇SQL+Pandas初步处理数据,见:


