Flask開發技巧之參數校驗


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM