flask_restful

flask-restful扩展

1.视图
1.1基本使用

from flask import Flask
from flask_restful import Api, Resource, output_json
import json

# json.dumps("data", ensure_ascii=False)

# 1.创建app对象
app = Flask(__name__)

# 不允许将字典中的中文编码成ascii码
# Flask-Restful中的中文编码成ascii码
app.config["RESTFUL_JSON"] = {
    
    "ensure_ascii": False}

# Flask不允许中文编码
# app.config["JSON_AS_ASCII"] = False
# /user/
# 获取服务器资源:GET
# 新建服务器资源:POST
# 删除服务器资源: DELETE
# 传输大量数据给服务器:PUT
# 局部更新: PATCH
# 请求参数:组织成json格式
# 响应数据: 以json格式返回
# 响应状态码应用以HTTTP标准状态码返回  201 401 403 404 405

# 2.将app对象包装成具备有restful风格的api对象
# 参数类型:app对象或者蓝图对象
api = Api(app)

# 3.自定义类视图 继承:Resource
class DemoResource(Resource):

    def get(self):
        # 返回字典,最终底层会将字典转换成json字符串
        return {
    
    "get": "可以显示中文吗?"}

    def post(self):
        return {
    
    "post": "post body"}

# 4.给类视图添加路由信息
api.add_resource(DemoResource, '/')

# api.add_resource(DemoResource, '/', endpoint="类视图的别名")

@app.route('/')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    app.run(debug=True, port=8000)

1.2视图装饰器

from flask import Flask
from flask_restful import Api, Resource

app = Flask(__name__)
# 1.创建api对象
api = Api(app)

def mydecorator1(func):
    def wrapper(*args, **kwargs):
        print("mydecorator1 dispatch")
        return func(*args, **kwargs)

    return wrapper

def mydecorator2(func):
    def wrapper(*args, **kwargs):
        print("mydecorator2 dispatch")
        return func(*args, **kwargs)

    return wrapper

# 需求:给类视图添加装饰器


# 2.自定义类视图
class DemoResource(Resource):
    # 方案1:给类视图中所有方法都添加上装饰器
    # method_decorators = [mydecorator1, mydecorator2]

    # 方案2:给类视图中指定方法添加指定的装饰器
    method_decorators = {
    
    
        "get": [mydecorator1, mydecorator2],
        "put": [mydecorator1]
    }

    def get(self):
        return {
    
    "foo": "get message"}

    def put(self):
        return {
    
    "put": "put message"}


# 3.添加路由信息
api.add_resource(DemoResource, '/index')

if __name__ == '__main__':
    app.run(debug=True, port=8000)

2.请求

from flask_restful import Api, Resource, output_json
from flask_restful.reqparse import RequestParser
# flask-restful自带的参数类型
from flask_restful.inputs import *
import re

app = Flask(__name__)
api = Api(app)


def get_userid(value):
    # user:1
    if re.match(r'^user:', value):
        # 截取id返回
        return value[5:]
    else:
        raise ValueError("invalid value")


class DemoResource(Resource):

    def get(self):
        # 1.创建解析对象
        parser = RequestParser()

        # 2.添加解析参数和解析规则
        # 默认会去get请求的查询字符串中提取参数
        # required=True 必传参数
        # location='json' 提取参数的位置 参数值为字符串 args form json files cookies headers
        # default=18 设置默认值
        parser.add_argument("name", required=True, location='json')
        parser.add_argument("age", default=18, location='json')

        # 参数类型 type
        # 1.python自带类型:type=int
        # parser.add_argument("number", required=True, location='json', type=int)
        # parser.add_argument("number", required=True, location='json', type=str)

        # 2.flask-restful自带的类型:date日期 regex正则表达式 int_range指定数据范围
        # 2020-09-20 00:00:00
        # <class 'datetime.datetime'>
        # 将时间字符串转换成datetime日期格式
        # parser.add_argument("number", required=True, location='json', type=date)

        # "Invalid argument: 300 超出限定范围就会报错
        # parser.add_argument("height", required=True, location='json', type=int_range(130, 250))

        # regex正则表达式 手机号码格式
        # parser.add_argument("number", required=True, location='json', type=regex(r'^1[3-9]\d{9}$'))

        # bool类型
        # parser.add_argument("number", required=True, location='json', type=boolean)

        # 3.自定义数据类型-自定函数
        parser.add_argument("number", required=True, location='json', type=get_userid)

        # 3.开启解析,获取解析结果
        ret = parser.parse_args()

        # 4.获取参数
        name = ret.name
        age = ret["age"]
        number = ret.number

        print(name)
        print(age)
        print(number)
        print(type(number))

        return {
    
    "get": "message"}

3.响应
3.1序列化

from flask_restful import Api, Resource, fields, marshal, marshal_with, output_json

app = Flask(__name__)

# 1.将app对象包装创建api对象 [用于管理类视图(资源)]
api = Api(app)


class User(object):

    def __init__(self):
        self.name = "curry"
        self.age = 18
        self.height = 180.8
        self.mylist = [30, 24]
        self.mydict = {
    
    
            "gender": True
        }

    def to_dict(self):
        my_dict = {
    
    
            "name": self.name,
            "age": self.age,
            "my_list": self.mylist,
            "my_dict": self.mydict
        }
        return my_dict


# 1.定义序列化规则字典
marshal_dict = {
    
    
    "name": fields.String(),
    "age": fields.Integer(default=18),
    "height": fields.Float(),
    "mylist": fields.List(fields.Integer),
    "mydict": fields.Nested({
    
    "gender": fields.Boolean})
}


# 2.使用marshal函数进行序列化

# 2.定义类视图  继承Resource
class DemoResource(Resource):
    method_decorators = {
    
    
        "post": [marshal_with(marshal_dict)]
    }

    def get(self):
        # 类视图响应的content-type默认变为json形式
        # 类视图的返回值可以是字典, 会被自动转为json字符串

        # 序列化方案1:
        # 创建用户对象
        user = User()
        # 利用marshal函数将用户对象序列化成字典
        return marshal(user, marshal_dict)

    # 序列化方案2:marshal_with装饰器
    # @marshal_with(marshal_dict)
    def post(self):
        # 加上了marshal_with装饰器,返回的user对象先经过装饰器序列化成字典,然后在返回
        user = User()
        return user

    # 序列化方案3:[推荐]
    def put(self):
        # 创建用户对象
        user = User()
        return user.to_dict()

# 3.api对象给类视图添加路由
api.add_resource(DemoResource, '/')

3.2自定义json

"""
需求:自定义json字符串的返回格式

原始json字符串数据:

{
    "username": "james",
    "number": 23
}

自定义返回的json字符串的格式:

{
    "message": "OK or ERROR",
    "data": {
            "username": "james",
            "number": 23
    }

}

方案1:修改源码 【不推荐】
方案2:复制源代码,使用装饰器api.representation()拦截output_json处理字典的方法,自己调整json格式


from flask import make_response, current_app
from flask_restful.utils import PY3
from json import dumps


# mediatype='application/json' 指明返回参数为json字符串类型
# @api.representation 拦截返回的字典数据
# @api.representation(mediatype='application/json')
def output_json(data, code, headers=None):
    # Makes a Flask response with a JSON encoded body

    settings = current_app.config.get('RESTFUL_JSON', {})

    if "message" not in data:
        data = {
            "message": "OK",
            "data": data
        }

    if current_app.debug:
        settings.setdefault('indent', 4)
        settings.setdefault('sort_keys', not PY3)

    # always end the json dumps with a new line
    # see https://github.com/mitsuhiko/flask/pull/1262
    dumped = dumps(data, **settings) + "\n"

    resp = make_response(dumped, code)
    resp.headers.extend(headers or {})
    return resp

"""
# 方案2:自定义返回的json格式
# 装饰器调用
api.representation(mediatype="application/json")(output_json)

# 2.定义类视图  继承Resource
class DemoResource(Resource):

    def get(self):
        # 类视图响应的content-type默认变为json形式
        # 类视图的返回值可以是字典, 会被自动转为json字符串
        return {
    
    'username': 'james', 'number': 23}

    def post(self):
        return {
    
    'foo': 'post'}

猜你喜欢

转载自blog.csdn.net/pigzww/article/details/108697337