第十屆鐵人賽 flask-restful DAY17-搞懂flask-restful請求參數處理

處理參數

昨日教程教授大家如何處理url上的參數,更進一步的說明就是所謂的routing,接下來的POST與PUT可就沒辦法僅是透過url傳遞,而是需要透過參數傳遞,所以今日教程旨在告訴大家如何解析請求的參數和POSTMAN 如何傳遞參數。

新增Users

先來看看截止昨日完成的use.py應該如下圖所示,已經完成get與delete兩個方法。

from flask_restful import Resource

users = [{
    'name': 'kirai',
}]

class User (Resource):

    def get(self, name):
        find = [item for item in users if item['name'] == name]
        if len(find) == 0:
            return {
                'message': 'username not exist!'
            }, 403
        user = find[0]
        if not user:
            return {
                'message': 'username not exist!'
            }, 403
        return {
            'message': '',
            'user': user
        }

    def post(self, name):
        pass

    def put(self, name):
        pass

    def delete(self, name):
        global users
        users = [item for item in users if item['name'] != name]
        return {
            'message': 'Delete done!'
        }

不過昨日User的GET方法沒辦法確認users內容到底有多少,這裡我們新增一個Users的Resource來提交取得所有user的GET方法,相信讀者們可以獨自完成此功能,而其內容如下所示:

class Users(Resource):
    def get(self):
        return {
            'message': '',
            'users': users
        }

這裡我們在修改app.py註冊users如下所示

api.add_resource(Users, '/users/')

最後修改POSTMAN新增一個GET請求來請求users的資料如下圖所示:

提交請求使用者的Url

相信到這邊為止提交請求可以得到下列響應:

請求使用者列表的響應

開發POST

在完成Users這個Resource後,我們今日接續實作post。

解析請求參數

在開始之前我們先要import一個函式庫進來,因為我們需要解析請求的參數,import的內容如下:

from flask_restful import reqparse

在importreqparse這函式庫之後首先要定義欲接受請求的參數內容,定義的方式如下:

    parser = reqparse.RequestParser()
    parser.add_argument('email', required=True, help='Email is required')
    parser.add_argument('password', required=True, help='Password is required')

如此即完成參數的定義。

type

這裡因為email``password`都是文字所以沒有特別指定其型別,若欲指定型別請使用參數`type`,假設參數是整數就使用`type=int來將請求參數轉換成Python的int型別。

required

這個參數指的是請求參數中此參數屬於必填,入無輸入flask-restful會直接回傳錯誤。

help

這參數設定的內容指的是當請求參數驗證失敗(型別不符、未填寫)會返還的訊息。

實作POST

在定義完請求參數後接下來要開始實作post方法了,在使用reqparse之後實作post的方式就變的很簡單了,這裡就請各位讀者看看下列例子了:

    def post(self, name):
        arg = self.parser.parse_args()
        user = {
            'name': name,
            'email': arg['email'],
            'password': arg['password']
        }
        global users
        users.append(user)
        return {
            'message': 'Insert user success',
            'user': user
        }

就這樣,我們user的post方法就告一段落,接下來就先使用POSTMAN來驗證該方法實作是否有問題。

設定POSTMAN

首先先選取collection內POST的方法,如下圖所示:

提交新增使用者的Url

接下來設定param頁籤的內容即可,這邊讀者們可以試試看透過json格式或是form的方式提交POST的request請求,如下圖所示:

JSON

新增使用者JSON格式返還成功例子

FORM

新增使用者FORM格式返還成功例子

相信兩個作法都能接受,因為在接受請求參數時沒有特別指定客戶端一定要傳送什麼格式的參數,若是要指定格式請見以下例子:

# Look only in the POST body
parser.add_argument('name', type=int, location='form')

# Look only in the querystring
parser.add_argument('name', type=int, location='args')

# Look only in the json
parser.add_argument('name', type=int, location='json')

# Look only in the multi location
parser.add_argument('name', type=int, location=['form', 'json'])

相信讀者們應該提交後都可以看到以下結果:

新增使用者請求成功響應

這時我們刪除email或password參數相信可以看到以下響應:

新增使用者請求失敗響應

這裡透過users的GET方法顯示內容如下:

透過取得使用者列表來檢查新增使用者請求結果

開發PUT

在開發完post要開發put相較之下就比較簡單,相信讀者應該有想法要如何處理了,這裡有個重點在於post是新增一筆資料,put是更新資料,以下就看看讀者實作的內容與筆者有什麼差別了。

    def put(self, name):
        arg = self.parser.parse_args()
        find = [item for item in users if item['name'] == name]
        if len(find) == 0:
            return {
                'message': 'username not exist!'
            }, 403
        user = find[0]
        user['email'] = arg['email']
        user['password'] = arg['password']
        return {
            'message': 'Update user success',
            'user': user
        }

如此就實作完put方法了,接下來用POSTMAN 來驗證功能是否正常即可。

驗證PUT

首先先選擇collection內的PUT方法,內容如下圖:

提交更新使用者的Url

並且把POST的例子複製過來,結果如下圖:

JSON

更新使用者JSON格式返還成功例子

FORM

更新使用者FORM格式返還成功例子

相信讀者們應該會收到以下響應:

更新使用者請求成功響應

接下來透過users的GET方法顯示內容如下:

透過取得使用者列表來檢查更新使用者請求結果

這時再修改一下name再提交PUT請求,應該會看到以下響應。

更新使用者請求失敗響應

截至目前為止把目前的code都摘錄在下方:

from flask_restful import Resource, reqparse

users = [{
    'name': 'kirai',
}]

class User (Resource):

    parser = reqparse.RequestParser()
    parser.add_argument('email', required=True, help='Email is required')
    parser.add_argument('password', required=True, help='Password is required')

    def get(self, name):
        find = [item for item in users if item['name'] == name]
        if len(find) == 0:
            return {
                'message': 'username not exist!'
            }, 403
        user = find[0]
        if not user:
            return {
                'message': 'username not exist!'
            }, 403
        return {
            'message': '',
            'user': user
        }

    def post(self, name):
        arg = self.parser.parse_args()
        user = {
            'name': name,
            'email': arg['email'],
            'password': arg['password']
        }
        global users
        users.append(user)
        return {
            'message': 'Insert user success',
            'user': user
        }

    def put(self, name):
        arg = self.parser.parse_args()
        find = [item for item in users if item['name'] == name]
        if len(find) == 0:
            return {
                'message': 'username not exist!'
            }, 403
        user = find[0]
        user['email'] = arg['email']
        user['password'] = arg['password']
        return {
            'message': 'Update user success',
            'user': user
        }

    def delete(self, name):
        global users
        users = [item for item in users if item['name'] != name]
        return {
            'message': 'Delete done!'
        }

class Users(Resource):
    def get(self):
        return {
            'message': '',
            'users': users
        }

小結

今天我們已經完成user的CRUD了,而基本flask-restful也告一段落,不過有些讀者應該會發現當email或是password提交""驗證會成功,但是這不是我們想要的結果,不過明天先使用POSTMAN來設定一下測試資料讓目前的code可以隨時驗證,以便後續的維護,敬請期待。

在〈第十屆鐵人賽 flask-restful DAY17-搞懂flask-restful請求參數處理〉中有 2 則留言

  1. arg = self.parser.parse_args()
    是不是多了一個self.
    導致執行時會出現 ” user object has no attribute ‘parser ‘”

    1. 建議你檢查一下你的程式碼,在我的範例中parser是class的一個屬性喔,如果parser = reqparse.RequestParser()寫在class外的話就不用加self了

發佈留言

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