Flask框架也是Python的同步web框架,Flask是一個基於Python開發並且依賴jinja2模板和Werkzeug WSGI服務的一個微型框架順便總結一下Python的同步web框架有Django(大而全,適合大型網站開發)、Flask(小而精,適合小型網站開發);非同步web框架有fastapi和sanic。
接下來我們詳細的研究一下flask框架吧!
一、快速使用Flask框架
安裝框架
pip install Flask
快速使用
from flask import Flask
app = Flask(__name__)
@app.route('/') # 裝飾器的方式註冊路由
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
Flask專案的目錄結構
二、配置檔案的配置方式
配置檔案的配置方式有好幾種,
- 配置方式一:直接在核心邏輯程式碼裡面配置(測試用)
app.debug=True # 除錯模式,提示資訊更詳細,修改程式碼不需要重啟,自動重啟
app.secret_key='dasdfasdfasd' # 秘鑰,只能 放debug和secret_key
- 配置方式二:直接使用app.config設定
app.config['DEBUG']=True
app.config['SECRET_KEY']='sdfasdfasd'
- 配置方式三:跟Django的路由配置類似使用py檔案(不常用)
app.config.from_pyfile("settings.py")
- 配置方式四:使用寫類的方式,常用方法
app.config.from_object('settings.DevelopmentConfig')
app.config.from_object('settings.ProductionConfig')
- 配置方式五:透過環境變數配置
app.config.from_envvar("環境變數名稱")
- 配置方式六:透過json檔案的方式
app.config.from_json("json檔名稱")
JSON檔名稱,必須是json格式,因為內部會執行json.loads
- 配置方式七:字典格式(配置中心)
app.config.from_mapping({'DEBUG': True})
三、路由系統
- 路由的本質
flask是基於裝飾器的,大部分都用裝飾器來做,少量可以抽取到一個urls.py種、flask路由的本質是app物件的add_url_rule完成路由的註冊。 - 路由的引數
rule URL規則
view_func 檢視函式名稱
defaults = None 預設值, 當URL中無引數,函式需要引數時,使用defaults = {'k': 'v'}為函式提供引數
endpoint = None, 路徑的別名,名稱,用於反向解析URL,即: url_for('名稱')
methods = None, 允許的請求方式,如:["GET", "POST"]
四、透過登入的邏輯快速瞭解框架
- 後端程式碼login.py
from flask import Flask, request, render_template, redirect, session,jsonify
app = Flask(__name__)
# 要使用session,必須設定秘鑰,秘鑰是配置資訊
app.secret_key = 'asdfasdfa33aef3aefads'
USERS = {
1:{'name':'張三','age':18,'gender':'男','text':"道路千萬條"},
2:{'name':'李四','age':28,'gender':'男','text':"安全第一條"},
3:{'name':'王五','age':18,'gender':'女','text':"行車不規範"},
}
# 1 建立templates資料夾,寫login.html
@app.route('/login', methods=['GET', 'POST'])
def index():
# 沒有request物件,使用全域性的request
# get請求,返回模板
if request.method == 'GET':
return render_template('login.html') # 新手四件套之一:返回模板
else:
# post請求,校驗資料
# 取出前端傳入的使用者名稱密碼,校驗
username = request.form.get('username') # 等同於django的的request.POST
password = request.form.get('password')
if username == 'lqz' and password == '123':
# 登入成功,儲存登入狀態 重定向到跟路徑 新手四件套之一:重定向
# 儲存到session中,session是全域性的
session['name'] = username
return redirect('/')
else:
return render_template('login.html', error='使用者名稱或密碼錯誤') # 注意跟django的render區分,要模板渲染的資料,直接key=value傳即可
@app.route('/')
def home():
# 校驗,登入成功,才能過來,不登入,重定向到登入頁面
if session.get('name'): # 有值說明登入了,沒有值說明沒有登入
return render_template('home.html',user_dict=USERS)
else:
return redirect('/login')
@app.route('/detail/<int:pk>')
def detail(pk):
if session.get('name'): # 有值說明登入了,沒有值說明沒有登入
user_detail = USERS.get(pk)
return render_template('detail.html', user=user_detail)
else:
return redirect('/login')
@app.route('/test')
def test():
return jsonify([{'name':'lqz','age':19}])
if __name__ == '__main__':
app.run()
- 前端頁面的程式碼
Home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>使用者列表</h1>
<table>
{% for k,v in user_dict.items() %}
<tr>
<td>{{k}}</td>
<td>{{v.name}}</td>
<td>{{v['name']}}</td>
<td>{{v.get('name')}}</td>
<td><a href="/detail/{{k}}">檢視詳細</a></td>
</tr>
{% endfor %}
</table>
</body>
</html>
Login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
<p>使用者名稱:<input type="text" name="username"></p>
<p>密碼:<input type="password" name="password"></p>
<input type="submit" value="登入"> {{error}}
</form>
</body>
</html>
Detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>名字是:{{user.name}}</p>
<p>年齡是:{{user['age']}}</p>
<p>性別是:{{user.get('gender')}}</p>
<p>{{user.text}}</p>
</body>
</html>
五、透過以上小案例的總結
- 註冊路由
app.route(路徑,methods=[請求方式get,post])
- 新手四件套
render_template 渲染模板 跟django有區別
redirect 重定向
return 字串 返回字串
jsonify 返回json格式
- 請求的request物件,是全域性的,直接匯入使用即可,在不同檢視函式中不會混亂
request.method 請求方式
request.form post請求的body體的內容轉成了字典
- session 全域性的,直接匯入使用即可,一定要指定秘鑰
app.secret_key = 'asdfasdfa33aef3aefads'
放值:session['name']='lqz'
取值:session.get('name')
- 模板的渲染
相容django的dtl
更強大,可以加括號,字典可以.get .values() .items()
{% for %}
- 轉換器
@app.route('/detail/<int:pk>')