flask基本使用
直接看代碼吧,非常容易上手:
# 創(chuàng)建flask應(yīng)用
app = Flask(__name__)
# 路由
@app.route("/index", methods=['GET'])
def index():
return "FLASK:歡迎訪問(wèn)主頁(yè)!"
if __name__ == "__main__":
app.run()
訪問(wèn)結(jié)果展示:
jinjia2模板引擎
jinja2 是 Flask 作者開(kāi)發(fā)的一個(gè)模板系統(tǒng),起初是仿 Django 模板的一個(gè)模板引擎,為 Flask 提供模板支持,由于其靈活,快速和安全等優(yōu)點(diǎn)被廣泛使用。當(dāng)我們開(kāi)發(fā) Web 應(yīng)用程序時(shí),通常需要將數(shù)據(jù)動(dòng)態(tài)地渲染到 HTML 模板中,而 Python jinja2 模版技術(shù)正是為此而生的。該引擎在一定程度上實(shí)現(xiàn)了前后端分離(前后端代碼層面的分離)。
模板目錄
創(chuàng)建templates文件夾,用于存放模板文件(HTML模板),flask默認(rèn)會(huì)在templates目錄下尋找對(duì)應(yīng)的html文件
模板語(yǔ)法
普通訪問(wèn)
模板中可以通過(guò)形如 {{obj.name}} 的形式訪問(wèn)后端的普通數(shù)據(jù),例如變量、對(duì)象、列表等。
<p>
{{ name }} <!-- name 就是一個(gè)變量 -->
{{ obj.name }} <!-- 提取 obj 對(duì)象的屬性 -->
{{ obj["name"] }} <!-- 和 obj.name 等效 -->
</p>
控制結(jié)構(gòu):遍歷
通過(guò)如下形式,實(shí)現(xiàn)遍歷的效果:
{% for item in students %}
<tr>
<td>{{item.name}}</td><td>{{item.age}}</td><td>{{item.sex}}</td>
</tr>
{% endfor %}
控制結(jié)構(gòu):判斷
支持類(lèi)似于if、else的表達(dá)式
<!-- 表達(dá)式 -->
{% if count > 10 %}
<p>There are too many items.</p>
{% else %}
<p>There are {{ count }} items.</p>
{% endif %}
控制結(jié)構(gòu):跳出循環(huán)、繼續(xù)執(zhí)行
{% for i in [1,2,3] %}
{% if i == 1 %}
{{ i }}
{% continue %}
{% else %}
{% break %}
{% endif %}
{% endfor %}
表達(dá)式
在模板中,支持python的表達(dá)式語(yǔ)法,例如:
-
-
- /
- and
- in
- or
- …
過(guò)濾器
過(guò)濾器就是函數(shù),把當(dāng)前的變量傳入過(guò)濾器,過(guò)濾器根據(jù)自己的功能對(duì)變量進(jìn)行相應(yīng)的處理,再返回對(duì)應(yīng)的值,并將結(jié)果渲染到網(wǎng)頁(yè)中,起到了數(shù)據(jù)處理的作用。例如:
- 絕對(duì)值
- 最大值
- 最小值
- …
模板的繼承與包含
django中的模板引擎,就具備模板的繼承和包含功能。同樣,jinjia2,也具備這樣的功能,起到了模板復(fù)用、模塊化開(kāi)發(fā)的效果。
繼承:
-----父親-----
{% block title %} {# 聲明一個(gè)名為 title 的block #}
<p>This is title</p>
{% block content %} {# title 內(nèi)部嵌套了一個(gè)名為 content 的block #}
{% endblock %}
{% endblock %}
{% block foot %}
<span>This is foot</span>
{% endblock %}
它里面定義了很多的 block
, 每個(gè) block 都有自己的名字(block的名字不能重復(fù)): {% block blok_name %}...{% endblock %}
,在 block 中,我們可以寫(xiě)入一些 html 代碼,讓子模板繼承。
各個(gè) block 之間是可以嵌套的
注意每個(gè) block 要有一個(gè) {% endblock %}
-----孩子-----
{% extends "mother.html" %} {# 繼承母版 #}
{% block content %} {# 重寫(xiě)某個(gè)block #}
<span>This is content, and the mother.html doesn't have this.</span>
{% endblock %}
{% block foot %}
{{ super() }} {# 繼承母版中的 foot block 的內(nèi)容 #}
<span>New foot content</span>
{% endblock %}
{% extend %}
非常關(guān)鍵:它告訴模板要繼承另一個(gè)模板。并且這個(gè)標(biāo)簽要放在模板的最上面。
當(dāng)然,繼承的標(biāo)簽可以寫(xiě)路徑: {% extends "layout/default.html" %}
如果子模板沒(méi)有重寫(xiě)母版中的某個(gè)block,則會(huì)默認(rèn)使用母版中的block。
包含:
{% include 'header.html' %}
{% include "sidebar.html" ignore missing %} {# ignore missing:如果找不到模板,可以忽略 #}
{% include ['special_sidebar.html', 'sidebar.html'] ignore missing %} {# 可以導(dǎo)入列表 #}
{% include "sidebar.html" ignore missing without context %} {# without context 可以不攜帶上下文 #}
{% include "sidebar.html" ignore missing with context %} {# with context 可以攜帶上下文 #}
上下文:其實(shí)就是模板中定義的變量,我們渲染時(shí)會(huì)將上下文傳遞給模板:template.render(context) ,而我們嵌套其他模板時(shí),也可以將它們中的上下文包含進(jìn)來(lái),這樣在當(dāng)前模板中也可以使用被嵌套模板中的上下文。(因?yàn)槟壳跋嚓P(guān)的實(shí)戰(zhàn)經(jīng)驗(yàn)較少,暫時(shí)不知道什么樣的場(chǎng)景會(huì)用到模板上下文)
場(chǎng)景分析:
- 代碼復(fù)用。html中的頭部部分、底部部分的標(biāo)簽,可以單獨(dú)抽象為一個(gè)模板,實(shí)現(xiàn)代碼復(fù)用,減少了代碼冗余。
- 模塊化開(kāi)發(fā)。比如一個(gè)頁(yè)面中的兩個(gè)板塊,A板塊抽象為一個(gè)模板,B板塊抽象為一個(gè)模板。通過(guò)包含的方式,將其引入,從而實(shí)現(xiàn)模塊發(fā)開(kāi)發(fā)的目的。
根據(jù)之前的經(jīng)驗(yàn),VUE、react均有相關(guān)代碼復(fù)用、模塊化開(kāi)發(fā)相關(guān)的支持。
個(gè)人的一些思考
關(guān)于前后端分離
無(wú)論是django還是flask的模板引擎,他們都是在一定程度上實(shí)現(xiàn)了前后端分離,但是還不是完全的前后端分離。
其中前后端分離體現(xiàn)在:
- 前后端代碼分離。前端頁(yè)面與后端處理程序分離,降低了前后端代碼耦合。
分離不完全體現(xiàn)在:
- 渲染的網(wǎng)頁(yè) 還是由后端程序來(lái)返回(某種程度上還是服務(wù)端渲染)
- 路由 依然在后端程序中進(jìn)行設(shè)置
- 模板中依然嵌入了某種語(yǔ)法,例如遍歷等。不過(guò)這個(gè)應(yīng)該不算,畢竟VUE、react中均有相關(guān)的數(shù)據(jù)處理的語(yǔ)法。
- 模板引擎提供了很多數(shù)據(jù)過(guò)濾器,而這些過(guò)濾器函數(shù) 與 JavaScript的函數(shù)/過(guò)濾器 功能上是重合的,如果說(shuō)分離得再?gòu)氐滓恍?,那么相關(guān)的數(shù)據(jù)處理應(yīng)該完全扔給前端的JavaScript來(lái)處理。
關(guān)于使用場(chǎng)景
目前,前后端分離,是一種WEB開(kāi)發(fā)的主流趨勢(shì)。那么,在python web開(kāi)發(fā)中,何時(shí)使用vue、react等前端框架?何時(shí)使用自帶的模板引擎?
我認(rèn)為:
- 如果是一些開(kāi)發(fā)周期較長(zhǎng)、規(guī)模較大、項(xiàng)目較為復(fù)雜的大型項(xiàng)目 或者說(shuō)以學(xué)習(xí)為目的,那么可以考慮使用vue、react等成熟的前端框架開(kāi)發(fā)。python僅用于返回?cái)?shù)據(jù),不適用其內(nèi)置的模板引擎。
- 如果就是非常簡(jiǎn)單的小型項(xiàng)目,那么完全可以使用django或者flask的模板引擎來(lái)進(jìn)行前端頁(yè)面的數(shù)據(jù)渲染,達(dá)到快速開(kāi)發(fā)的目的。畢竟,使用vue、react等框架,需要單獨(dú)建立項(xiàng)目,還需要進(jìn)行各種配置,掌握各種命令。相比之下,這種模板引擎,就顯得非常容易上手。
附代碼
后端
from flask import Flask, jsonify
from flask import render_template
from flask_cors import CORS
# 創(chuàng)建flask應(yīng)用
app = Flask(__name__)
# 配置跨域請(qǐng)求。r'/*' 是通配符,讓本服務(wù)器所有的 URL 都允許跨域請(qǐng)求
CORS(app, resources=r'/*')
# 路由
@app.route("/", methods=['GET'])
@app.route("/index", methods=['GET'])
def index():
return "FLASK:歡迎訪問(wèn)主頁(yè)!"
# 返回json數(shù)據(jù)
@app.route("/getOneData", methods=['GET'])
def getOneData():
student = {
"age": 15,
"name": "zhangsan",
"sex": "man"
}
return jsonify(student)
# 返回網(wǎng)頁(yè)
# 利用jinjia2渲染引擎,向模板中渲染數(shù)據(jù)
@app.route("/studentInfo", methods=['GET'])
def studentInfo():
student = {
"age": 15,
"name": "zhangsan",
"sex": "man"
}
students = [
{
"age": 101,
"name": "zhangsan",
"sex": "man"
},
{
"age": 123,
"name": "lisi",
"sex": "man"
},
{
"age": 336,
"name": "wangwu",
"sex": "man"
}
]
hello = "歡迎來(lái)到flask項(xiàng)目!"
return render_template('student.html', title='學(xué)生信息', hello=hello, student=student, students=students)
if __name__ == "__main__":
# 0.0.0.0代表所有主機(jī)均可以訪問(wèn),開(kāi)啟之后可通過(guò)服務(wù)器的IP地址訪問(wèn)網(wǎng)站
# 默認(rèn)端口為5000
# app.run(port=5001, debug=True)
app.run(host='0.0.0.0', port=5001, debug=True)
前端
<html>
<style>
/* Table Head */
table{
border-spacing: 0;
}
#table-6 thead th {
background-color: rgb(128, 102, 160);
color: #fff;
border-bottom-width: 0;
}
/* Column Style */
#table-6 td {
color: #000;
}
/* Heading and Column Style */
#table-6 tr, #table-6 th {
border: 1px solid rgb(128, 102, 160);
}
/* Padding and font style */
#table-6 td, #table-6 th {
padding: 5px 10px;
font-size:30px;
font-family: Verdana;
font-weight: bold;
}
td{
border:1px solid rgb(128, 102, 160) ;
}
</style>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{hello}}</h1>
<h1>姓名:{{student.name}}</h1>
<h1>年齡:{{student.age}}</h1>
<h1>性別:{{student.sex}}</h1>
<br>
<br>
<br>
<table id="table-6">
<thead>
<tr>
<th>姓名</th><th>年齡</th><th>性別</th>
</tr>
</thead>
<tbody>
<tr>
<td>item.name</td><td>item.age</td><td>item.sex</td>
</tr>
<tr>
<td>item.name</td><td>item.age</td><td>item.sex</td>
</tr>
{% for item in students %}
<tr>
<td>{{item.name}}</td><td>{{item.age}}
{{item.age}}</td><td>{{item.sex}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
參考鏈接
某個(gè)jinjia2的教程
http://docs.jinkan.org/docs/jinja2/index.html
博客園某博主文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-732385.html
https://www.cnblogs.com/wztshine/p/16054582.html文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-732385.html
到了這里,關(guān)于Flask基本教程以及Jinjia2模板引擎簡(jiǎn)介的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!