原文:http://www.catonlinepy.tech/
聲明:原創不易,未經許可,不得轉載html
經過學習次日的內容,你將會對模板有所瞭解,而且知道爲何要使用模板,以及使用模板有什麼好處。這一天的學習內容涉及到的代碼都會託管到github上,貓姐再次強調,在學習本課內容時必定要本身嘗試手敲代碼,遇到問題再到github上去查看代碼,若是實在不知道如何去解決問題,能夠在日誌下面留言說明具體狀況。前端
視圖函數主要有兩個做用,一個是處理業務邏輯,另外一個是給用戶返回相關內容。在大型應用中,若是把業務邏輯和返回響應內容放在一塊兒的話,這樣會增長代碼的複雜度,而且也很差維護。因此模板它就承擔了視圖函數的另一個做用:返回響應內容。這樣就能夠實現業務邏輯和響應內容的分離,將全部的html代碼都存放到模板中,而視圖函數中只須要專心處理好業務邏輯便可。python
下面貓姐經過一個簡單的例子來展現爲何要引入模板,如下是這個例子的代碼組織結構:git
(miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary$ tree . ├── day2 │ ├── run.py │ └── template_demo │ ├── __init__.py │ └── routes.py └── README.md
首先來創建次日的代碼目錄,與第一天的課程相似,先激活虛擬環境miao_venv,建立方法都是同樣的:github
# 進入到虛擬環境目錄,激活虛擬環境 maojie@Thinkpad:~/flask-plan/$source miao_venv/bin/activate # 再到flask-course-primary目錄下建立次日的課程day2目錄 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary$ mkdir day2 # 進入day2目錄 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary$ cd day2 # 新建template_demo目錄 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day2$ mkdir template_demo # 進入到template_demo目錄 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day2$ cd template_demo/ # 在template_demo目錄中新建__init__.py文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day2/template_demo$ touch __init__.py # 在template_demo包中新建routes.py路由文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day2/template_demo$ touch routes.py # 在day2目錄下新建run.py文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day2/$ touch run.py
在template_demo包的__init__.py中輸入以下代碼:web
# 如下是__init__.py文件中的代碼,咱們逐行進行解釋 from flask import Flask # 從flask包中導入Flask類 app = Flask(__name__) # 經過Flask類建立一個app實例 from template_demo import routes # 從template_demo包中導入routes文件裏的全部代碼
在routes.py文件中輸入以下代碼,包括響應內容中的HTML代碼:flask
# 從template_demo包中導入app實例 from template_demo import app @app.route('/') def index(): user = {'username':'貓姐'} # 創建一個user字典 # 返回HTML格式的響應內容 return ''' <html> <head> <title>Home Page-模板的使用-喵星在線</title> </head> <body> <h1>Hello,''' + user['username'] + '''!</h1> </body> </html>'''
在第一課中,視圖函數返回的字符串是「你好,喵星在線」,而今天的課程,經過擴展,return 語句中呈現了完整的HTML代碼。若是你們對HTML語言不熟悉,能夠在w3school在線教程中進行學習。瀏覽器
最後在day2目錄下run.py文件中輸入以下代碼:app
from template_demo import app # 從template_demo包中導入app實例 if __name__ == "__main__": app.run(debug=True) # app實例調用本身的run函數 # 解釋:debug=True,每次代碼有改動時,後臺會自動檢測到,避免本身每次中止、重啓後臺程序
用第一課運行程序的方法(python run.py),將程序運行起來,而後在瀏覽器中打開網址 http://localhost:5000/,查看結果:框架
這樣應用就運行起來了。你們有沒有發現,若是我後面還想擴展其餘功能,index視圖函數裏面的代碼也會相應的變多,而且應用的視圖函數和關聯的URL也會相應的增長。若是我還想將HTML裏面的佈局更改一下的話,那我不得不更改每一個視圖函數裏面的HTML標籤,這樣是不利於長久管理以及應用的擴張。
因此,這裏就出來了模板的概念,模板有助於實現業務邏輯和響應內容之間的分離,是實際項目開發中必須使用的一個技術。在Flask中,模板文件(即html文件)須要單獨存放在包內的templates目錄下。
在template_demo包中新建templates目錄,用來存放模板文件:
(miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day2/template_demo$ mkdir templates
建立模板文件index.html,並輸入HTML代碼:
# 建立模板文件index.html (下面是使用touch命令建立的,你們也能夠在ide集成開發環境中建立該文件) (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day2/template_demo/templates$ touch index.html # 在index.html中輸入以下代碼,這裏title,html_user變量是從視圖函數中傳進來的 <html> <head> <title>{{ title }}-模板的使用-喵星在線</title> </head> <body> <h1>Hello,{{ html_user.username }}!</h1> </body> </html>
在上面的HTML代碼中,惟一值得關注的就是{{ ... }}裏面的內容,這些變量都是從視圖函數中傳遞進來的。
要渲染模板文件,還須要從Flask框架中導入render_template()這個函數,以下:
# 在routes.py文件中,從flask庫中導入render_template類 from flask import render_template
在視圖函數中調用render_template時,須要傳入模板的文件名以及模板參數的變量列表。視圖函數中進行以下操做,即可使用模板了:
# routes.py文件中輸入以下代碼 from flask import render_template # 從flask庫中導入render_template對象 from template_demo import app # 從template_demo包中導入app實例 @app.route('/') def index(): user = {'username':'貓姐'} # 創建一個user字典 return render_template('index.html', title='HomePage', html_user=user)
在render_template函數中,index.html表示的是模板的文件名。title,html_user表示在模板文件中須要使用的變量。user表示是視圖函數中的user變量,user變量賦值給html_user變量,在模板中渲染的就是user變量的值了。這樣,routes.py文件中的代碼就好看多了,從而就實現了業務代碼和前端html代碼分離的效果,並且也更便於管理往後愈加複雜的html代碼。
用一樣的方式運行程序,效果應用和沒有使用模板的狀況是同樣的,以下圖
下面咱們介紹一下模板的其它經常使用知識點,主要包括模板中if條件語句的使用,for循環語句的使用以及模板的繼承方法。
說到模板中的條件語句,這裏不得不說說Jinja2的概念。它是python下被普遍應用的模板引擎,是一種被設計自動生成文檔的簡單格式。在模板語言中,須要把變量傳給模板,而後替換成模板特定位置上的佔位變量名。它的使用方法很簡單,須要用到兩對大的花括號,{{ ... }},它裏面傳入的是變量名。
而Jinja2的條件語句,使用方法也很簡單,它用到的是一對花括號,裏面再加兩個百分號,像這樣{% %}。而後裏面能夠寫if,else,for等,可是以if,for開頭,必須有閉合if,for的標籤。以下所示:
# jinja2中 if控制語句的使用 {% if title %} {{ ... }} {% else %} {{ ... }} {% endfor %} # jinja2中 for控制語句的使用 {% for i in username %} {{ ... }} {% endfor %}
下面是在模板index.html文件添加一個條件語句的示例:
<html> <head> {% if title %} <title>{{ title }} -模板的使用-喵星在線</title> {% else %} <title>模板的使用-喵星在線</title> {% endif %} </head> <body> <h1>Hello, {{ html_user.username }}!</h1> </body> </html>
若是視圖函數給模板傳遞了title參數,那麼它就會走if語句,若是沒有傳遞參數,則會走else語句,而不是顯示一個空的標題。在本例中,沒有給render_template函數的title參數傳入值,因此它會走else語句,效果以下圖所示:
要理解Jinja2中是如何在模板中使用循環的,咱們能夠在路由函數中增長一些其它的信息,以下面使用posts列表變量保存了一些假的日誌信息,並將posts變量傳遞給了模板文件中將使用的htm_posts變量:
from flask import render_template from template_demo import app @app.route('/') def index(): user = {'username': '貓姐'} # 日誌由一個列表組成,其中裏面包含兩個字典,裏面各有author和content字段 posts = [ { 'author': {'username': '貓姐'}, 'content': 'This day is Beautiful day!' }, { 'author': {'username': '貓哥'}, 'content': 'The flower is beautiful!' } ] return render_template('index.html', title='HomePage', html_user=user, html_posts=posts)
在index.html模板文件中,經過上面介紹的for循環語法,完成對htm_posts列表變量中每一篇日誌的渲染:
<!DOCTYPE html> <html lang="en"> <head> {% if title %} <title>{{ title }} -模板的使用-喵星在線</title> {% else %} <title>模板的使用-喵星在線</title> {% endif %} </head> <body> <h1>Hello, {{ html_user.username }}!</h1> {% for post in html_posts %} <!--for循環開始--> <div> <p> {{ post.author.username }} says:<b>{{ post.content }}</b> </p> </div> {% endfor %} <!-- for循環結束--> </body> </html>
打開瀏覽器URL,效果以下圖所示:
咱們在寫一個web應用時,隨着裏面的功能增多,代碼也會相應的變多,這時可能會有一些重複的HTML代碼,爲了去除大量重複的代碼,這時候出現了模板繼承的概念。它也是Jinja2的特性,它的特色就是將模板中相同的部分代碼轉移到一個基模板中,後面其它模板要使用的時候,只須要繼承基模板就能夠了。
在template_demo/templates目錄下,新建layout.html文件,而後在layout.html中寫入以下代碼:
# 在templates目錄下新建layout.html文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day2/templates$ touch layout.html # layout.html文件中寫入以下代碼: <html> <head> {% if title %} <title>{{ title }} - 模板的使用-喵星在線</title> {% else %} <title>模板的使用-喵星在線</title> {% endif %} </head> <body> {% block content %} {% endblock %} </body> </html>
在這個layout.html模板中,使用block控制塊來肯定子模板插入代碼的位置。子模板經過引用block能夠在裏面添加本身想要的內容。
下面index.html文件,能夠直接繼承layout.html文件中的內容,而無需重複實現這段代碼,這樣在能夠簡化index.html裏面的內容:
# index.html中改成以下內容 {% extends "layout.html" %} # 繼承基模板裏面的內容 {% block content %} # 從新填寫content塊的內容 <h1>Hi, {{ html_user.username }}!</h1> {% for post in html_posts %} <div> <p>{{ post.author.username }} says: <b>{{ post.content }}</b></p> </div> {% endfor %} {% endblock %}
打開瀏覽器的URL,效果以下圖所示:
學習完次日的教程,咱們掌握了以下技能:
第三天的內容,咱們將會帶領你們一塊兒瞭解什麼是表單,表單如何建立,次日的內容就到這裏,喜歡的同窗們能夠在下面點贊留言,或是訪問個人博客地址:http://www.catonlinepy.tech/ 加入咱們的QQ羣進一步交流學習!
你們能夠到github上獲取今天教程中的全部代碼:https://github.com/miaojie19/...
具體下載代碼的命令以下:
# 使用git命令下載flask-course-primary倉庫全部的代碼 git clone https://github.com/miaojie19/flask-course-primary.git # 下載完成後,進入day2目錄下面,便可看到今天的代碼 cd flask-course-primary cd day2