首先,要看你學沒學過Django,若是學過Django的同窗,請從頭看到尾,若是沒有學過Django的同窗,而且不想學習Django的同窗,請繞過第一部分。html
一、Django主要特色是大而全,繼承了不少組件,例如:Models Admin Form等等,無論你用獲得用不到,反正它全都有,屬於全能型框架前端
二、Tornado主要特色是原生異步非阻塞,在IO密集型應用和多任務處理上佔據絕對性的優點,屬於專一型框架web
三、Flask主要特色小而輕,原生組件幾乎爲0,三方提供的組件請參考Django很是全面,屬於短小精悍型框架json
Django一般用於大型Web應用,因爲內置組件足夠大,因此使用Django開發能夠一鼓作氣flask
Tornado一般用於API後端應用,遊戲服務後臺,其內部實現的異步非阻塞真是穩得一批後端
Flask一般應用於小型應用和快速構建應用,其強大的三方庫,足以支撐一個大型的Web應用瀏覽器
Django優勢是大而全,缺點也就暴露出來了,這麼多的資源一次性所有加載,確定會形成一部分的資源浪費安全
Tornado優勢是異步,缺點是乾淨,連個session都不支持服務器
Flask優勢是精悍簡單,缺點是你不會cookie
總結:
Flask: 1、輕,短小精悍 2、快,三行代碼開啓服務 缺點: 一、組件大部分來源三方,flask-admin,flask-session 2、flask大版本更新,組件更新速度慢 Django: 1、大而全,admin,models,Form,中間件,session 2、一個框架解決全部問題 缺點: 1、一旦啓動,全部資源所有加載,用不到的,浪費了 2、太大了,結構複雜 3、全部的組件,所有由Django自身控制 Tornado: 1、原生websocktet 2、異步io 3、非阻塞 缺點: 三方及原生組件幾乎爲0
pip install Flask
from flask import Flask app = Flask(__name__) app.run()
執行控制檯輸出:
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) |
默認端口是5000,訪問頁面:
由於沒有定義路由,因此報404。可是服務是起來了!
from flask import Flask app = Flask(__name__) @app.route("/") def index(): return "HelloWorld" app.run()
重啓程序,刷新頁面
實現了Flask的第一個HelloWorld程序,解讀一下代碼
from flask import Flask # 導入Flask類 app = Flask(__name__) # 實例化Flask對象app @app.route("/") # app中的route裝飾器 def index(): # 視圖函數 return "HelloWorld" # 返回響應提 # 監聽地址爲0.0.0.0,表示服務器的全部網卡 # 5000是監聽端口 # debug=True表示啓動debug模式。當代碼有改動時,Flask會自動加載,無需重啓! app.run("0.0.0.0", 5000, debug=True) # 啓動Flask服務
注意:默認的debug模式是關閉的。若有代碼改動,須要重啓flask才能生效!可是開啓debug模式,代碼一有改動,會馬上加載,無需重啓!
還有一點,app=Flask(__name__)。這裏面的__name__表示標識模塊的名字的一個系統變量
還能夠是app=Flask("asdfasdf"),這樣運行也沒有問題。那麼爲何要用__name__呢?
@app.route("/") # app中的route裝飾器 def index(): # 視圖函數 return "HelloWorld" # HttpResponse
在Flask中的HttpResponse在咱們看來其實就是直接返回字符串
from flask import Flask from flask import redirect # 導入flask中的redirect app = Flask(__name__) # app中的route裝飾器,用來指定視圖函數的URL地址 @app.route("/redi") def redi(): # 視圖函數 return redirect("/") # redirect跳轉至"/" @app.route("/") def index(): # 視圖函數 return "hello" if __name__ == "__main__": app.run("0.0.0.0", 5000, debug=True)
每當訪問"/redi"這個地址的時候,視圖函數redi會觸發redirect("/")跳轉到url地址:"/"並會觸發"/"對應的視圖函數index()
訪問url:http://127.0.0.1:5000/redi
查看網頁工具,查看網絡。它經歷了2次請求!
編輯文件demo.py,代碼以下
from flask import Flask # 導入Flask類 from flask import render_template # 導入flask中的render_template app = Flask(__name__) @app.route("/home") def home(): # 視圖函數 # 渲染html模板,返回html頁面 return render_template('home.html') if __name__ == '__main__': app.run("0.0.0.0", 5000, debug=True)
在當前py文件目錄中建立templates,在此目錄下建立文件home.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>Flask</h1> </body> </html>
重啓flask,訪問home頁面,效果以下:
HTML模板渲染是每一個Web框架中都必須有的
注意:若是要使用render_template返回渲染的模板,請在項目的主目錄中假如一個目錄templates,不然可能會有一個jinja2的異常哦
遇到上述的問題,基本上就是你的template的路徑問題
爲何必定要建立templates文件夾呢?叫abc行不行呢?不行!看這一行代碼
app = Flask(__name__)
使用Ctrl+鼠標左鍵,點擊Flask,查看源碼
def __init__( self, import_name, static_url_path=None, static_folder='static', static_host=None, host_matching=False, subdomain_matching=False, template_folder='templates', instance_path=None, instance_relative_config=False, root_path=None ):
看到template_folder變量沒有?文件均價必須叫這個名字!
注意:個人flask程序,是直接用新建py文件寫的。因此這一行代碼,會票黃
return render_template('home.html')
怎麼解決呢?很簡單!執行目錄就行了
右鍵templates文件夾--→Mark Directory as--→Template Folder
選擇yes
選擇Jinja2,Flask中默認的模板語言是Jinja2
Django的模板語言爲Django,其實Django底層也是用Jinja2開發的。其餘模板語言同理!
後續會講到flask模板語法,你會發現,和Django幾乎是同樣的!
注意:若是直接使用Pycharm建立Flask項目,是不存在這個問題的!
前期學習Flask,要先本身手動折騰,後期就能夠用Pycharm建立了!
每一個框架中都有處理請求的機制(request),可是每一個框架的處理方式和機制是不一樣的
爲了瞭解Flask的request中都有什麼東西,首先咱們要寫一個先後端的交互,基於HTML + Flask寫一段先後端的交互
先寫一段兒HTML form表單中提交方式是post action地址是/req
在templates目錄建立文件login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>歡迎登錄</h1> <form action="/req" method="post"> <p> <input type="text" name="user" placeholder="請輸入用戶名"> </p> <p> <input type="password" name="pwd" placeholder="請輸入密碼"> </p> <input type="submit" value="提交"> </form> </body> </html>
寫好一個標準form表單,一點提交,就向後端提交一個POST請求過去了,後端的接收方式就666了
首先要從flask包中導入request模塊
from flask import Flask # 導入flask類 from flask import render_template # 導入flask中的render_template from flask import request # 導入flask中的request app = Flask(__name__) @app.route("/login") def login(): return render_template("login.html") @app.route("/req") def home(): # 視圖函數 print(request) return "ok" if __name__ == '__main__': app.run("0.0.0.0", 5000, debug=True)
重啓flask,訪問登錄頁面
輸入表單,提交以後,報錯!提示請求方式不被容許!
爲何呢?由於默認路由只容許GET訪問。那麼須要加一個參數methods,容許POST訪問
from flask import Flask # 導入flask類 from flask import render_template # 導入flask中的render_template from flask import request # 導入flask中的request app = Flask(__name__) @app.route("/login") def login(): return render_template("login.html") @app.route("/req",methods=["POST"]) # 只容許POST def home(): # 視圖函數 print(request) # request對象 print(request.method) # POST看來可使用這種方式來驗證請求方式 # ImmutableMultiDict([('user','xiao'),('pwd','123')]) print(request.form) # ImmutableMultiDict 它看起來像是Dict,使用字典方式取值 print(request.form["user"]) # xiao print(request.form.get("pwd")) # 123 # 字典迭代器對象,keys表示獲取全部值 print(request.form.keys()) # 既然是迭代器,就可使用for循環了 for i in request.form.keys(): print(i) return "ok" if __name__ == '__main__': app.run("0.0.0.0", 5000, debug=True)
從新提交一次,就能夠了!
查看Pycharm控制檯輸出:
<Request 'http://127.0.0.1:5000/req' [POST]> |
解釋一個@app.route("/req",methods=["POST"]):
methods=["POST"] 表明這個url地址只容許POST請求,是個列表也就是意味着能夠容許多重請求方式,例如GET之類的
一、request.method之確定知道前端用什麼方式提交的
Flask的request中給咱們提供了一個method屬性裏面保存的就是前端的請求方式
print(request.method) # POST 看來可使用這種方式來驗證請求方式
二、request.form之拿他來舉例的話再好不過了
Form表單中傳遞過來的值 使用request.form中拿到
print(request.form) # ImmutableMultiDict([('user', 'xiao'), ('pwd', '123')]) # ImmutableMultiDict 它看起來像是的Dict 就用Dict的方法取值試一下吧 print(request.form["user"]) # xiao print(request.form.get("pwd")) # 123 # 看來所有才對了, ImmutableMultiDict 彷佛就是個字典,再來玩一玩它 print(list(request.form.keys())) # ['user', 'pwd'] 看來是又纔對了 #若是以上全部的方法你都以爲用的不爽的話 req_dict = dict(request.form) print(req_dict) # 若是你以爲用字典更爽的話,也能夠轉成字典操做(這裏有坑)
三、request.args之你能看見的url參數全在裏面
request.args中保存的是url中傳遞的參數
先把後端請求代碼改動一下,容許POST和GET
from flask import Flask # 導入flask類 from flask import render_template # 導入flask中的render_template from flask import request # 導入flask中的request app = Flask(__name__) @app.route("/login") def login(): return render_template("login.html") @app.route("/req",methods=["POST","GET"]) # 只容許POST和GET def home(): # 視圖函數 print(request.args) # ImmutableMultiDict([('id','1'),('age','20')]) print(request.args["id"]) # 1 print(request.args.get("age")) # 20 print(list(request.args.keys())) # ['id','age'] print(list(request.args.values())) # ['1','20'] req_dict = dict(request.args) # {'id':['1'],'age':['20']} print(req_dict) return "ok" if __name__ == '__main__': app.run("0.0.0.0", 5000, debug=True)
而後使用URL地址直接傳遞參數
而後會在控制檯中看到,ImmutableMultiDict
ImmutableMultiDict([('id', '18'), ('age', '20')]) |
request.args與request.form的區別就是:
request.args 是獲取url中的參數
request.form 是獲取form表單中的參數
四、request.values 之 只要是個參數我都要
改動一下前端頁面(login.html)代碼:
<form action="/req?id=1&age=20" method="post"> |
改動後端代碼:
from flask import Flask # 導入flask類 from flask import render_template # 導入flask中的render_template from flask import request # 導入flask中的request app = Flask(__name__) @app.route("/login") def login(): return render_template("login.html") @app.route("/req",methods=["POST","GET"]) # 只容許POST和GET def home(): # 視圖函數 print(request.values) # CombinedMultiDict([ImmutableMultiDict([('id', '1'), ('age', '20')]), ImmutableMultiDict([('user', 'xiao'), ('pwd', '123')])]) print(request.values.get("id")) # 1 print(request.values["user"]) # Oldboy # 這回喜歡直接操做字典的小夥伴們有驚喜了!to_dict()方法能夠直接將咱們的參數所有轉爲字典形式 print(request.values.to_dict()) # {'user': 'xiao', 'pwd': '123', 'id': '1', 'age': '20'} return "ok" if __name__ == '__main__': app.run("0.0.0.0", 5000, debug=True)
這是讓咱們在使用form表單提交的同時使用url參數提交
訪問登錄頁面,點擊提交,查看Pycharm控制檯輸出:
CombinedMultiDict([ImmutableMultiDict([('age', '20'), ('id', '1')]), ImmutableMultiDict([('user', 'xiao'), ('pwd', '112')])]) |
若是url和form中的Key重名的話,form中的同名的key中value會被url中的value覆蓋
http://127.0.0.1:5000/req?id=1&user=20
修改login.html
<form action="/req?id=1&user=20" method="post"> |
從新訪問登錄頁面,再次提交。
查看Pycharm控制檯輸出:
CombinedMultiDict([ImmutableMultiDict([('id', '1'), ('user', '20')]), ImmutableMultiDict([('user', 'xiao'), ('pwd', '123')])]) 1 20 {'user': '20', 'pwd': '123', 'id': '1'} |
發現user變成了20,若是url和form中key重名的話,form中的同名的key中value會被url中的value覆蓋
五、request.cookies 之 存在瀏覽器端字符串兒也會一塊兒帶過來
前提是你要開啓瀏覽器的cookies,request.cookies是將cookies中信息讀取出來
修改demo.py中的home視圖函數
def home(): # 視圖函數 print(request.cookies) return "ok"
從新登錄一次,查看Pycharm控制檯輸出:
{'csrftoken': '5dbnoXpHe4dYUPZqCejRBleKc5HznLKY2sAgmTLqxSjL2kBPKLYAt9yxvPlNNMHf'} |
六、request.headers 之 請求頭中的祕密
用來獲取本次請求的請求頭
修改demo.py中的home視圖函數
def home(): # 視圖函數 print(request.headers) return "ok"
從新登錄一次,查看Pycharm控制檯輸出:
Connection: keep-alive |
七、request.data 之 若是處理不了的就變成字符串兒存在data裏面
你必定要知道request是基於mimetype進行處理的
mimetype的類型以及字符串:http://www.w3school.com.cn/media/media_mimeref.asp
若是不屬於上述類型的描述,request就會將沒法處理的參數轉爲Json存入到data中
其實咱們能夠將request.data,json.loads一樣能夠拿到裏面的參數
修改demo.py中的home視圖函數
def home(): # 視圖函數 print(request.data) return "ok"
從新登錄一次,查看Pycharm控制檯輸出:
b'' |
爲何是空的呢?注意:request處理不了的就變成字符串存在data裏面!
由於它能處理,因此纔是空的!
八、request.files 之 給我一個文件我幫你保管
若是遇到文件上傳的話,request.files裏面存的是你上傳的文件,可是Flask在這個文件的操做中加了必定的封裝,讓操做變得極爲簡單
首先改下前端代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>歡迎登錄</h1> <form action="/req" method="post" enctype="multipart/form-data"> <p> <input type="file" name="file"> </p> <input type="submit" value="提交"> </form> </body> </html>
再改後端代碼:
from flask import Flask # 導入flask類 from flask import render_template # 導入flask中的render_template from flask import request # 導入flask中的request app = Flask(__name__) @app.route("/login") def login(): return render_template("login.html") @app.route("/req",methods=["POST","GET"]) # 只容許POST和GET def home(): # 視圖函數 print(request.files) # ImmutableMultiDict([('file', <FileStorage: 'abc.txt' ('text/plain')>)]) print(request.files['file']) # <FileStorage: 'abc.txt' ('text/plain')> my_file = request.files["file"] my_file.save("123.txt") # 保存文件,裏面能夠寫完整路徑+文件名 return "ok" if __name__ == '__main__': app.run("0.0.0.0", 5000, debug=True)
訪問登錄頁面
上傳一個文件,好比是abc.txt
點擊提交,效果以下:
查看Pycharm控制檯輸出:
ImmutableMultiDict([('file', <FileStorage: 'abc.txt' ('text/plain')>)]) |
這樣咱們就成功的保存了一個名叫123.txt的文件了,操做仍是很簡單的。保存目錄爲當前py文件目錄!
注意:前端頁面必須設置enctype=「multipart/form-data」,不然提交時,會報錯
九、request.獲取各類路徑 之 這些方法不必記,可是要知道它存在
修改後端代碼
def home(): # 視圖函數 # 獲取當前的url路徑 print(request.path) # /req # 當前url路徑的上一級路徑 print(request.script_root) # # 當前url的所有路徑 print(request.url) # http://127.0.0.1:5000/req # 當前url的路徑的上一級所有路徑 print(request.url_root) # http://127.0.0.1:5000/ return "ok"
直接訪問頁面
查看Pycharm控制檯輸出:
/req http://127.0.0.1:5000/req |
十、request.json 之 前提你得告訴是json
若是在請求中寫入了「application/json」使用request.json則返回json解析數據,不然返回None
修改後端代碼:
def home(): # 視圖函數 # 獲取json數據 print(request.json) return "ok"
使用postman發送一個json數據
查看返回值
查看Pycharm控制檯輸出:
{'id': 1} |
Flask中默認的模板語言是Jinja2 ,如今咱們來一步一步的學習下Jinja2。
首先咱們要在後端定義幾個字符串,用於傳遞到前端
STUDENT = {'name':'韓雪','age':24,'gender':'女'} |
可是前提咱們要知道Jinja2模板中的流程控制
Jinja2模板語言中的for
{% for foo in session %}
{{ foo }}
{% endfor %}
Jinja2模板語言中的if
{% if session %}
{% elif session %}
{% else %}
{% endif %}
接下來,咱們對這幾種狀況分別進行傳遞,並在前端顯示成表格
一、使用STUDENT字典傳遞至前端
後端demo.py
from flask import Flask # 導入flask類 from flask import render_template # 導入flask中的render_template from flask import request # 導入flask中的request app = Flask(__name__) STUDENT = {'name': '韓雪', 'age': 24, 'gender': '女'} STUDENT_LIST = [ {'name': '韓雪', 'age': 24, 'gender': '女'}, {'name': '舒暢', 'age': 23, 'gender': '女'}, {'name': '唐嫣', 'age': 25, 'gender': '女'}, ] STUDENT_DICT = { 1: {'name': '韓雪', 'age': 24, 'gender': '女'}, 2: {'name': '舒暢', 'age': 23, 'gender': '女'}, 3: {'name': '唐嫣', 'age': 25, 'gender': '女'}, } @app.route("/student") def student(): return render_template("student.html", student=STUDENT) if __name__ == '__main__': app.run("0.0.0.0", 5000, debug=True)
前端student.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>學生列表</h3> <div>{{ student }}</div> <table border="1px"> <tr> <td>{{ student.name }}</td> <td>{{ student["age"] }}</td> <td>{{ student.get("gender") }}</td> </tr> </table> </body> </html>
從新flask,訪問頁面
從這個例子中,能夠看出來,字典傳入前端Jinja2模板語言中的取值操做,與Python中的Dict操做極爲類似,而且多了一個student.name的對象操做
二、STUDENT_LIST列表傳入前端Jinja2模板的操做:
後端:
@app.route("/student_list")
def student_list():
return render_template("student.html",student=STUDENT_LIST)
前端:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>學生列表</h3> <div>{{ student }}</div> <table border="1px"> {% for foo in student %} <tr> <td>{{ foo }}</td> <td>{{ foo.name }}</td> <td>{{ foo.get("age") }}</td> <td>{{ foo["gender"] }}</td> </tr> {% endfor %} </table> </body> </html>
訪問頁面,注意:路徑改了,效果以下:
這裏咱們能夠看出,若是是須要循環遍歷的話,Jinja2給咱們的方案是
{% for foo in student %} |
修改前端:
<div>{{ student }}</div> <table border="1px"> {% for foo in student %} <tr> <td>{{ foo }}</td> </tr> {% endfor %} </table>
訪問頁面,注意:路徑改了,效果以下:
三、STUDENT_DICT大字典傳入前端Jinja2模板
後端:
@app.route("/student_dict") def student_dict(): return render_template("student.html",student=STUDENT_DICT)
前端:
<table border="1px"> {% for foo in student %} <tr> <td>{{ foo }}</td> <td>{{ student.get(foo).name }}</td> <td>{{ student[foo].get("age") }}</td> <td>{{ student[foo]["gender"] }}</td> </tr> {% endfor %} </table>
在遍歷字典的時候,foo實際上是至關於拿出了字典中的Key
訪問頁面,注意:路徑變了,效果以下:
四、結合所喲的字符串所有傳遞前端Jinja2模板
後端:
@app.route("/allstudent") def allstudent(): return render_template("student.html", student=STUDENT, student_list=STUDENT_LIST, student_dict=STUDENT_DICT)
前端:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>學生列表</h3> <div> _____________________________________</div> Welcome to : student <div>{{ student }}</div> <table border="1px"> <tr> <td>{{ student.name }}</td> <td>{{ student["age"] }}</td> <td>{{ student.get("gender") }}</td> </tr> </table> <div> _____________________________________</div> Welcome to : student_list <div>{{ student_list }}</div> <table border="1xp"> {% for foo in student_list %} <tr> <td>{{ foo }}</td> <td>{{ foo.name }}</td> <td>{{ foo.get("age") }}</td> <td>{{ foo["gender"] }}</td> </tr> {% endfor %} </table> <div> _____________________________________</div> Welcome to : student_dict <div>{{ student_dict }}</div> <table border="1xp"> {% for foo in student_dict %} <tr> <td>{{ foo }}</td> <td>{{ student_dict.get(foo).name }}</td> <td>{{ student_dict[foo].get("age") }}</td> <td>{{ student_dict[foo]["gender"] }}</td> </tr> {% endfor %} </table> </body> </html>
訪問頁面,注意,路徑改了,效果以下:
這裏能夠看出來render_template中能夠傳遞多個關鍵字
五、利用**{}字典的方式傳遞參數
前端不變(標題4的前端代碼)
後端:
@app.route("/allstudent") def allstudent(): return render_template("student.html", **{"student": STUDENT, "student_list": STUDENT_LIST, "student_dict": STUDENT_DICT})
刷新頁面,效果同上!
6.1.safe: 此時你與HTML只差一個safe
後端代碼:
from flask import Flask from flask import render_template app = Flask(__name__) @app.route("/") def index(): tag = '<input type="text" name="user" value="xiao">' return render_template("index.html", tag=tag) if __name__ == '__main__': app.run("0.0.0.0", 5000, debug=True)
在templates目錄下新建文件index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {{ tag }} </body> </html>
訪問首頁,效果以下:
彷佛和咱們想要的結果不太同樣,有兩種解決方案。
第一種,從前端入手
修改前端代碼:
{{ tag|safe }}
刷新頁面,效果以下:
還有一種方式是從後端入手
後端代碼:
from flask import Flask from flask import render_template from flask import Markup # 導入flask中的Markup模塊 app = Flask(__name__) @app.route("/") def index(): tag = '<input type="text" name="user" value="xiao">' # Markup幫助我們在HTML的標籤上作了一層封裝,讓Jinja2模板語言知道這是一個安全的HTML標籤 markup_tag = Markup(tag) print(markup_tag, type(markup_tag)) # <input type='text' name='user' value='DragonFire'> <class 'markupsafe.Markup'> return render_template("index.html", tag=markup_tag) if __name__ == '__main__': app.run("0.0.0.0", 5000, debug=True)
模板中執行函數,首先在文件中定義一個函數
後端代碼:
from flask import Flask from flask import render_template app = Flask(__name__) # 定義一個函數,把它傳遞給前端 def a_b_num(a, b): return a + b @app.route("/") def index(): return render_template("index.html", tag=a_b_num) if __name__ == '__main__': app.run("0.0.0.0", 5000, debug=True)
前端代碼:
<body> {{ tag }} <br> {#傳入2個參數#} {{ tag(99,1) }} </body>
刷新頁面,效果以下:
看到結果就是函數加()執行獲得的結果
還能夠定義全局函數,無需後端傳遞給前端,Jinja2直接就能夠執行的函數
後端代碼:
from flask import Flask from flask import render_template app = Flask(__name__) @app.template_global() # 定義全局模板函數 def a_b_sum(a, b): return a + b @app.template_filter() # 定義全局模板函數 def a_b_c_sum(a, b, c): return a + b + c @app.route("/") def index(): return render_template("index.html", tag="") if __name__ == '__main__': app.run("0.0.0.0", 5000, debug=True)
前端代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {#函數#} {{ a_b_sum(99,1) }} <br> {#過濾器#} {{ 1 | a_b_c_sum(197,2) }} </body> </html>
兩個函數的調用方式不太同樣
尤爲是@app.template_filter()它的調用方式比較特別,這是兩個Flask中的特殊裝飾器
刷新頁面,效果以下:
若是咱們前端頁面有大量重複頁面,不必每次都寫,可使用模板複用的方式複用模板
前端代碼:
index.html文件中的內容