Flask開發技巧之參數校驗
本人平時開發中使用的,或者學習到的一些flask開發技巧整理,需要已有較為扎實的flask基礎。
1、請求參數分類
一般來說,前端發送過來的請求中,大致包含以下三種類型的參數,分別是url路徑參數,url查詢參數,還有目前前后端分離開發中最常見的json格式的數據。
- url路徑參數
/v1/user/1
url路徑參數即類似於上述例子中的參數,直接帶在url路徑中,可變化,flask針對這種參數,已經直接提供了支持,例:
@app.route('/v1/user/<int:id>')
- url查詢參數
/v1/user?page=1&pageSize=10
類似於這種帶在url中的問號后面的鍵值對並且用&連接的參數稱為url查詢參數
- json格式的參數
{
"name": "xiaowang",
"age": 1
}
而json格式的參數就更不用多說了,header中帶有Content-Type:Application/json傳輸過來的json格式的數據就是這樣的。
2、解決方案使用到的庫
這里我們為了解決參數校驗的問題,一定是要將參數校驗的部分抽離出來,按照面向對象的思想,隱藏參數校驗的具體過程,交給特定的類去解決。這樣,我們在視圖函數中,不會出現冗余的參數校驗代碼,會使整個視圖函數顯得簡短易讀。
這里我們需要安裝兩個庫
pip install WTForms
pip install WTForms-JSON
后續方法建立在wtforms庫上擴展,所有wtforms庫原有的操作,全部都有效,可以繼續使用。如果不熟悉wtforms,需要先學習一下。
3、針對url查詢參數與一般json格式
首先解釋一下,經過我的探究(本人能力有限,可能無法擴展實現),使用普通的wtforms庫,無法接受復雜格式的json數據,只能接受普通格式的json數據以及url查詢參數進行校驗。
- 普通格式的json參數舉例
{
"name": "xiaowang",
"age": 1,
"address": "beijing"
}
- 復雜格式的json參數舉例
{
"category": {
"category_name": "電腦",
"category_id": 2
},
"address_list": [
"beijing",
"shanghai"
]
"name": "xiaohong",
"age": 1,
}
實現方法,繼承wtforms庫中的Form,實現自己的基類參數驗證類BaseForm
class BaseForm(Form):
def __init__(self):
data = request.get_json()
args = request.args.to_dict()
super(BaseForm, self).__init__(data=data, **args)
def validate_for_api(self):
valid = super(BaseForm, self).validate()
if not valid:
raise ParameterException(msg=self.errors)
return self
這里進行一下說明,BaseForm的__init__方法實例化對象的時候首先通過flask中的request對象將普通json數據和查詢參數args拿到,通過調用父類的方法將參數初始化。
而validate_for_api()方法則調用父類中的validate()進行參數校驗,如果校驗結果不通過,那么將錯誤信息放入msg交給異常類400處理,異常處理我們已經在上一篇詳細講述。如果校驗通過,那么就將校驗完成的form返回。
使用舉例
針對一個請求url為
/v1/user?user_id=1
請求體為
{
"username": "xiaoming",
"age": 1
}
那么使用如下類:
class UserForm(BaseForm):
user_id = IntegerField()
username = StringField()
age = IntegerField()
form = UserForm().validate_for_api()
即可完成參數校驗,如果校驗出錯,會直接向前端返回400,並且錯誤信息也會附帶返回。
4、針對復雜json格式數據
單純的使用wtforms庫無法實現復雜json格式數據的處理,於是在我的探索下,發現還有一個wtforms的擴展庫,叫wtforms-json,通過這個庫可以實現。
於是擴展原先的BaseForm,使用wtforms-json,仿照原先基類,我實現的新基類如下。
import wtforms_json
class JsonForm(Form):
@classmethod
def init_and_validate(cls):
wtforms_json.init()
form = cls.from_json(request.get_json())
valid = form.validate()
if not valid:
raise ParameterException(msg=form.errors)
return form
繼承上述新的基類,這樣的Form就可以實現任意json格式的數據的校驗了。
使用舉例
針對一個請求,請求體如果為
{
"username": "xiaochen",
"age": 1,
"address_list": [
"beijing",
"shanghai"
],
"info": {
"name": "hi",
"length": 5
},
"area_list": [
{
"level1": "北京",
"level2": "朝陽"
},
{
"level1": "北京",
"level2": "海淀"
}
]
}
通過如下Form就可以實現校驗
class InfoForm(JsonForm):
name = StringField()
length = IntegerField()
class AreaForm(JsonForm):
level1 = StringField()
levle2 = StringField()
class DemoForm(JsonForm):
username = StringField()
age = IntegerField()
address_list = FieldList(
StringField(),
min_entries=1
)
info = FormField(InfoForm)
area_list = FieldList(
FormField(AreaForm),
min_entries=1
)
form = DemoForm().init_and_validate()
如此就可以實現復雜json數據的校驗
關於flask的參數校驗,以上就是我目前掌握的一些技巧,如有錯誤歡迎指出。
博客園: https://www.cnblogs.com/luyuze95/
GitHub: https://github.com/luyuze95