
文 / 秦未
OK,今天學(xué)習(xí)Flask的請(qǐng)求上下文與響應(yīng),我們先看一看Flask請(qǐng)求和響應(yīng)的過程示意圖:

首先我們從瀏覽器發(fā)送一個(gè)請(qǐng)求到服務(wù)端,F(xiàn)lask得到了這個(gè)請(qǐng)求以后,這個(gè)請(qǐng)求將會(huì)由路由系統(tǒng)接收,接著Flask會(huì)對(duì)這個(gè)請(qǐng)求的信息做一些預(yù)處理工作,將客戶的信息封裝成request對(duì)象,它包含此次訪問的所有信息,從request中我們可以獲取一些變量和參數(shù),然后我們?cè)谝晥D函數(shù)中處理這些數(shù)據(jù)并生成合適的html文件傳回給我們的客戶端,通常情況下我們并不需要直接的去產(chǎn)生一個(gè)response(響應(yīng))對(duì)象,但其實(shí)我們也可以對(duì)它做更細(xì)致化的處理,利用這個(gè)response(響應(yīng))對(duì)象,我們能完成更高級(jí)的數(shù)據(jù)輸出。
1.表單提交以及文件上傳的處理
上一篇文章我們已經(jīng)簡(jiǎn)單了解了一下request對(duì)象,我們知道在客戶端請(qǐng)求的時(shí)候,通過GET或者POST方式到達(dá)后端時(shí),我們就需要獲取request.method的值,來對(duì)數(shù)據(jù)做進(jìn)一步處理。
我們先來看看之前的login.html,我們將里面的內(nèi)容擴(kuò)展一下:
<!--/app/templates/blog/login.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登錄頁</title>
</head>
<body>
<h1>HTPP方法:{{ method }}</h1>
<form action="{{ url_for('.login') }}" method="post" enctype="multipart/form-data">
<input type="text" name="username" placeholder="username">
<input type="password" name="password" placeholder="password">
<input type="file" name="file">
<input type="submit">
</form>
</body>
</html>
接下來我們?cè)趺传@取提交的參數(shù)呢?很簡(jiǎn)單看代碼:
# /app/app.py
@app.route('/login/', methods=['GET', 'POST'])
def login():
# 判斷請(qǐng)求方式
if request.method == 'POST':
# POST方式時(shí)數(shù)據(jù)是在form里面
username = request.form.get('username')
password = request.form.get('password')
else:
# GET方式時(shí)數(shù)據(jù)是在args里面
username = request.args.get('username')
password = request.args.get('password')
return render_template('blog/login.html', method='GET')
我想有點(diǎn)Python基礎(chǔ)的人都應(yīng)該看得明白,我們的值是在一個(gè)字典里面,獲取值的方法可以用['變量名'],不過我建議用get方法,因?yàn)檫@樣不會(huì)報(bào)錯(cuò)。
這樣我們就完成了取值的操作,不過你會(huì)發(fā)現(xiàn)我還增加了一個(gè)提交文件的選項(xiàng),那么后端是如何獲取文件并保存的呢?
這也不難,繼續(xù)看修改后的代碼:
注意:前面帶 + 號(hào)的為新增加內(nèi)容,復(fù)制時(shí)請(qǐng)自行刪除 + 。
# - from flask import Flask, render_template, request, redirect, url_for
+ from flask import Flask, render_template, request, redirect, url_for
+ from os import path
from werkzeug.routing import BaseConverter
+ from werkzeug.utils import secure_filename
@app.route('/login/', methods=['GET', 'POST'])
def login():
# 判斷請(qǐng)求方式
if request.method == 'POST':
# POST方式時(shí)數(shù)據(jù)是在form里面
username = request.form.get('username')
password = request.form.get('password')
# 獲取文件
my_file = request.files.get('file')
# 獲取當(dāng)前路徑
basepath = path.abspath(path.dirname(__file__))
# 將路徑連接
upload_path = path.join(basepath, 'static/uploads/')
# 保存文件并將文件名獲取封裝
my_file.save(upload_path + secure_filename(my_file.filename))
# 跳轉(zhuǎn)upload函數(shù)
return redirect(url_for('upload'))
else:
# GET方式時(shí)數(shù)據(jù)是在args里面
username = request.args.get('username')
password = request.args.get('password')
return render_template('blog/login.html', method='GET')
# 新增加的路由和函數(shù)
@app.route('/upload')
def upload():
return '<h1>上傳成功!</h1>'
然后我們還要在static目錄下新建立一個(gè)uploads文件夾,運(yùn)行,上傳一個(gè)文件試試。
注意一點(diǎn):上傳文件時(shí)form中一定要加上enctype="multipart/form-data"哦!否則它會(huì)什么都不做。
2.cookies的獲取以及設(shè)置
首先我們導(dǎo)入make_response這個(gè)包:from flask import ... make_response
再將index函數(shù)修改一下:
@app.route('/')
def index():
# 獲取cookies
# username = request.cookies.get('username')
# 封裝render_template
response = make_response(render_template('blog/index.html', **{
'text': 'Hello, World',
}))
# 設(shè)置cookies--參數(shù)1:名稱,參數(shù)2:值,expires指定過期時(shí)間;(記得導(dǎo)入datetime模塊!)
outdate = datetime.datetime.today() + datetime.timedelta(days=30)
response.set_cookie('username', 'admin', expires=outdate)
return response
運(yùn)行:

---end---