第十屆鐵人賽 flask-restful DAY20-搞懂如何用marshmallow解析請求參數

使用marshmallow

在昨日告訴大家怎麼安裝flask-marshmallow,並且在我們的flask-restful應用程序中加載了flask-marshmallow,今日要開始使用marshmallow的設定來解析請求參數。

marshmallow元素

在這邊我們透過建立一個解析請求參數內容的方式介紹marshmallow內含的元素,首先我們先介紹schema。

schema

我們可以透過這一個schema來建立我們預期請求參數的內容的基本結構,下面例子我們建立一個UserSchema來定義我們接收到使用者的請求參數所包含的元素:

from common.ma import ma

class UserSchema(ma.Schema):
    email = ma.Str()
    password = ma.Str()

在定義UserSchema之前我們需要把先前的flask-marshmallow函式庫import進來,因為所有自訂義的marshmallow的schema都要繼承Marshmallow.Schema,接下來我們在UserSchema定義他有兩個屬性emailpassword

field

定義UserSchema的兩個屬性就是透過marshmallow的field來限定屬性的型別,例如上面例子就是指定emailpassword這兩個屬性的型別是字串,而marshmallow的field有很多種,以下針對下列幾點加以說明。

  • Str, Int, Bool, Float
  • DateTime, LocalDateTim
  • Email
  • Nested

Str, Int, Bool, Float

這就是一些常用的基本型別,所以先不針對這部分加以說明了。

DateTime, LocalDateTim

這是一些時間的型別,所以也不加以說明了。

Email

這就限制字串內容是Email的格式。

Nested

這個Nested比較特別,就是一個複雜的型別他可以透過傳入另外一個Schema告訴目前的Schema知道那個屬性是該Schema的型別,這樣說來很抽象就讓大家看看下列例子:

class ASchema(ma.Schema):
    name = ma.Str()
    password = ma.Str()

class BSchema(ma.Schema):
    aItem = ma.Nested(ASchema)

這個marshmallow的field的內容還蠻多的就不在此一一說明,有興趣的讀者可以看一下API文件

validate

由於先前的內容會驗證所需內容一定要提交,但是沒有驗證格式是否相符,所以我們再進一步修正上述的例子如下:

from common.ma import ma

class UserSchema(ma.Schema):
    email = ma.Email(required=True)
    password = ma.Str(required=True)

經過修正之後我們針對email的內容加規範,所以當提交內容不符合Email的規範時他會提示錯誤內容,並且該屬性的內容會是None,不過password若是提交空字串他還是會通過,因此我們再加以修正如下:

from common.ma import ma
from marshmallow import validate


class UserSchema(ma.Schema):
    email = ma.Email(required=True)
    password = ma.Str(required=True, validate=[
                      validate.Length(min=6, max=36)],)

透過validate.Length我們可以指定密碼的長度落在6~36之間,所以當下次提交請求時若是password提交空字串時會得到驗證失敗的錯誤。

在flask-restful內加入Schema

首先我們再models內加一個schema的資料夾,並在schema內加入一個user_schema.py的檔案,最後把上述的內容貼到user_schema.py檔案內,接下來我們針對user.py這個Resource加以修改,首先先加入以下修改:

from models.schema.user import UserSchema

當然第一步是先將先前寫好的UserSchema給import進來,在來下一步是產生一個UserSchema的實體如下列所示:

user_schema = UserSchema()

最後就是在處理POST與PUT方法時使用user_schema來解析傳入參數的內容,詳細內容請見以下例子:

        json_data = request.json
        result = user_schema.load(json_data)

        if len(result.errors) > 0:
            return result.errors, 433

        user = {
            'name': name,
            'email': result.data['email'],
            'password': result.data['password']
        }

不過這裡就有個缺點,就是需要明確的定義請求的方式是透過form或是json格式,像上述的是透過json方式,如果改成form的方式傳遞就會解析失敗,如果傳遞的方式是form的話就要修改成以下內容:

        json_data = request.form

小結

今日的內容教授大家如何使用marshmallow來定義UserSchema,並透過field.Email來驗證請求參數內容格式,以及透過validate.Length來限制輸入長度,最後透過範例教授大家如何加UserSchema加入到我們的專案之中。接下來明日的教程先教大家如何整理至今為止的user.py,敬請期待。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *