本篇是系列文章的第三篇:
(一)需求分析&技術實作
(二)初步搭建Django環境
(三)頁面布局&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的左中右布局)。
我們構思的整個布局如下圖所示:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicGcq5iYfJzY5M2MlVWM0IWY1QWYyQ2NllDNiRGNyM2NzkDO5gTNtIjdvwVbvNmLn1WaopnLzMWaw9CXvwlOzBHd0hWPsJXdmYDM3YjZkJGNzQDNl1SOhRGOtETMiVWLwMDMw0SM5MTOiFmY20DZpV3ZmITPlBXe0ZyPldWYtl2LcdXZpZ3Lc12bj5SZjVjL5h3byBnLzATLn1Wavw1LcpDc0RHaiojIsJye.jpg)
根據此設計,我們需要搭建相應的Django模闆架構,并充分利用其模闆繼承特性,其中主要需要了解base-extend機制以及block和include兩個主要的模闆語句。
在這裡我省略了講解Django模闆加載器的部分,其實這一部分也是有講究的,尤其是對于多個app的更大型的工程。
按照官網推薦的結構,先在本例的chpa_data建立檔案夾templates,再在templates内建立和app同名的檔案夾chpa_data,再在其内建立Django的html模闆檔案。首先,建立一個base.html代表這個模闆的基礎結構(可以稱之為基礎模闆或父模闆):
<!-- 載入靜态檔案 更早版本可能會用load staticfiles -->
{% load static %}
在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:
<
這裡第一次出現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:
<
注意header和footer的代碼就是這麼短,是不需要extends語句的。
而base裡預留的{% block body %}{% endblock body %}部分是可以複用的,我們可以測試兩個頁面分别繼承的情況,這兩個頁面的開頭語句都是:
{%
我們可以有一個靜态的項目首頁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準備測試:
{%
此時Django模闆架構完畢,再确認一次項目結構:
我們可以修改上一章中views.py的index方法做個測試,因為在模闆裡預留了{{ data }}tag,我們不希望再傳一個整體的HttpResponse了,而是希望傳一個包含data鍵值的context。修改代碼如下:
from
可以看到首頁已經發生了改變。
如果render到display模闆會怎樣呢?
return
很明顯我們為分析功能設計的filter-display左右布局也生效了。
本章是回報出問題最多的地方,特再次總結一遍容易踩坑的要點:
- 項目結建構議完全按照截圖。在教程的早期版本我曾經把模闆html檔案直接放在templates檔案夾下,後來一些朋友回報Django進階版本會報錯,是以請不要這麼做。
- 按照截圖推薦的結構的情況下,所有要引用模闆path的extends, include和render等語句,路徑一定都是'chpa_data/xxx.html'而不是'xxx.html'。這是因為加載模闆是根據絕對位置(templates檔案夾)而不是相對位置。
- 隻有預留block的子模闆要在頭部加入對應的extends語句,include的子模版不需要加。
下一篇SQL+Pandas初步處理資料,見:
https://zhuanlan.zhihu.com/p/143627683zhuanlan.zhihu.com