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