Flask-restful 用法及自定義引數錯誤資訊

wuqiangroy發表於2019-02-16

flask-restful 是一款比較好用的 flask 外掛,它不僅自動為我們實現了資料的 json 化,還能對傳入引數進行驗證,優雅的替代了 form 表單。

程式碼結構:

app
 |_api
 |  |_ __init__.py
 |  |_ parser.py
 |  |_ view.py
 |
 |_ __init__.py
 |_ code.py
 |_ util.py
app.py

具體程式碼如下:

parser.py

from flask_restful.reqparse import RequestParser

parser = RequestParser()
parser.add_argument("id", type=int, location="args", required=True)
# get 請求為args, post請求為json

在 view 中的使用

view.py

from flask_restful import Resource

from app.util import make_result
from .parser import parser


class Test(Resource):
    def get(self):
        req = parser.parse_args(strict=True)
        id = req.get("id")
        return make_result(data={"id": id})

還有 __init__.py 檔案設定路由

__init__.py

from .view import Test
from flask_restful import Api
from flask import Blueprint

api = Blueprint("api", __name__) # 設定藍圖
resource = Api(api)
resource.add_resource(Test, "/") # 設定路由

util.py 為一個設定檔案, 用來放我們自己定義的輸出規範。

util.py

from flask import jsonify
from app.code import Code


def make_result(data=None, code=Code.SUCCESS):
    return jsonify({"code": code, "data": data, "msg": Code.msg[code]})

code.py 是我們自定義的錯誤碼

code.py

class Code:
    SUCCESS = 1200
    NO_PARAM = 1300

    msg = {
        SUCCESS: "success",
        NO_PARAM: "no param"
    }

app.py 為啟動檔案

app.py

from flask import Flask
from app.api import api

app = Flask(__name__)
app.register_blueprint(api)


if __name__ == "__main__":
    app.run(debug=True)

當我們執行 python app.py 的時候,程式便啟動了起來。

我們在瀏覽器中輸入:localhost:5000/?id=123

即可看到:

{
"code": 1200,
"data":{
"id": 123
},
"msg": "success"
}

那當我們輸入: localhost:5000/?id=api

得到了:

{
"message":{
"id": "invalid literal for int() with base 10: `api`"
}
}

很明顯,我們期望得到一個 int 型的 id,這裡給了一個 str 型別的字串,於是得到了 status_code 為 40 0的 response。

我們肯定是希望以我們自己的定義訊息來輸出,即:

{
"code": 1300,
"data": null,
"msg": "no param"
}

flask-restful 並沒有提供相應的 api,經過檢視原始碼,發現 flask-restful abort 的程式碼是改寫的 flask 的 abort 程式碼,於是我們也改寫 flask-restful 的 abort 程式碼。

flask abort 原始碼:

def abort(status, *args, **kwargs):
    return _aborter(status, *args, **kwargs)

非常簡單。

flask-restful 的 abort 原始碼:

def abort(http_status_code, **kwargs):
    try:
        original_flask_abort(http_status_code)
    except HTTPException as e:
        if len(kwargs):
            e.data = kwargs
        raise

也是非常的簡單,這裡的 original_flask_abort 即 flask 的 abort。

那現在改程式碼就很容易了,只要 http_status_code == 400,那麼就是我們的引數沒有接受正確,需要爆出格式化以後的錯誤。

在 app.py 中修改:

app.py

from flask import Flask, abort
import flask_restful
from app.api import api
from app.util import make_result
from app.code import Code

app = Flask(__name__)
app.register_blueprint(api)


def custom_abord(http_status_code, *args, **kwargs):
    # 只要http_status_code 為400, 報引數錯誤
    if http_status_code == 400:
        abort(make_result(code=Code.NO_PARAM))
    # 正常返回訊息
    return abort(http_status_code)

# 把flask_restful中的abort方法改為我們自己定義的方法
flask_restful.abort = custom_abord


if __name__ == "__main__":
    app.run(debug=True)

現在再次執行 python app.py

瀏覽器輸入:http://localhost:5000/?id=api

即可得到:

{
"code": 1300,
"data": null,
"msg": "no param"
}

輸入:http://localhost:5000/?id=111 檢測一下正常輸出:

{
"code": 1200,
"data":{
"id": 111
},
"msg": "success"
}

完美!

相關文章