flask十五:(一)RESTful Response

插件1: flask-restful

文档:https://flask-restful.readthedocs.io/en/latest/index.html

安装:pip install flask-restful

 

插件2: flask-restless,测试版本

插件32: flask-reset-jsonapi

 

初始化restful风格路由:  使用flask_restful.Api加载app,加载路由

from flask import Flask
# from application.views import init_view
from application.apis import init_api
from application.ext import init_ext
from application.settings import ENV
from application.middleware import load_middleware


def create_app(env):
    app = Flask(__name__)

    # 初始化项目配置
    config_object = ENV.get(env)
    app.config.from_object(config_object)

    # 初始化路由相关
    # init_view(app)
    init_api(app)

    # 初始化扩展: models, migrate, Session持久化
    init_ext(app)

    # 加载中间件
    load_middleware(app)

    return app

 

from flask_restful import Api
from application.apis.goods_api import GoodsListResource
from application.apis.Test2Apis import Hello2Resource
api = Api()


def init_api(app):
    api.init_app(app)


api.add_resource(GoodsListResource, '/goods/')
api.add_resource(Hello2Resource, '/hello2/')

 

模型:

from application.ext import db


class BaseModel(db.Model):
    __abstract__ = True
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)

    def save(self):
        try:
            db.session.add(self)
            db.session.commit()
        except Exception as e:
            print(e)
            return False
        return True


class Goods(BaseModel):
    name = db.Column(db.String(64))
    price = db.Column(db.Float, default=0)

 

restful示例1:

  • 使用flask_restful.Api加载app,加载路由(初始化restful)
  • 使用flask_restful.Resource定义资源:get,post
  • 先定义序列化字典,再使用flask_restful.marshal或marshal_with序列化Model对象

 

from flask import request
from flask_restful import Resource, abort, fields, marshal_with, marshal

from application.models import Goods

goods_fields = {
    "name": fields.String,
    "price": fields.Float
}


class GoodsListResource(Resource):
    # # 方式1
    # @marshal_with(goods_fields)
    # def get(self):
    #     goods = Goods.query.first()
    #     return goods   # {"name": "apple", "price": 1.236}

    # 方式2
    def get(self):
        goods = Goods.query.first()
        # {"code": 200, "message": "success", "data": {"name": "apple", "price": 1.236}}
        return {"code": 200, "message": "success", "data": (marshal(data=goods, fields=goods_fields))}

    @marshal_with(goods_fields)
    def post(self):
        name = request.form.get("name")
        price = request.form.get("price")

        goods = Goods()
        goods.name = name
        goods.price = price

        if not goods.save():
            abort(http_status_code=400)
        # return {"code": 200, "message": "success", "data": (marshal(data=goods, fields=goods_fields))}
        return goods

 


restful示例2: 级联fields

from flask import request
from flask_restful import Resource, abort, fields, marshal_with, marshal

from application.models import Goods

goods_fields = {
    "name": fields.String,
    "price": fields.Float
}
single_goods_fields = {
    "data": fields.Nested(goods_fields),
    "code": fields.Integer,
    "message": fields.String
}


class GoodsListResource(Resource):
    # 方式3,数据嵌套
    @marshal_with(single_goods_fields)
    def get(self):
        goods = Goods.query.first()
        # {"code": 200, "message": "success", "data": {"name": "apple", "price": 1.236}}
        return {"code": 200, "message": "success", "data": goods}

 

from flask import request
from flask_restful import Resource, abort, fields, marshal_with, marshal

from application.models import Goods

goods_fields = {
    "name": fields.String,
    "price": fields.Float
}
multi_goods_fields = {
    "data": fields.List(fields.Nested(goods_fields)),
    "code": fields.Integer,
    "message": fields.String
}


class GoodsListResource(Resource):
    # 方式3,数据嵌套
    @marshal_with(multi_goods_fields)
    def get(self):
        goods_list = Goods.query.all()
        # {"code": 200, "message": "success", "data": [{"name": "apple", "price": 1.236}]}
        return {"code": 200, "message": "success", "data": goods_list}


restful示例3: 更改字段属性,如显示字段、默认值


from flask import request
from flask_restful import Resource, abort, fields, marshal_with, marshal

from application.models import Goods

goods_fields = {
    "show_name": fields.String(attribute='name'),
    "price": fields.Float
}


class GoodsListResource(Resource):
    @marshal_with(goods_fields)
    def get(self):
        goods = Goods.query.first()
        return goods   # {"show_name": "apple", "price": 1.236}

 field源码:


field.Url示例
a.定义单条记录的url和endpoint
api.add_resource(GoodsResource, '/goods/<int:id>/', endpoint="single_goods")

 b.定义格式化字段

goods_fields = {
    "show_name": fields.String(attribute='name'),
    "price": fields.Float,
    "uri": fields.Url("single_goods", absolute=True)
}
single_goods_fields = {
    "data": fields.Nested(goods_fields),
    "code": fields.Integer,
    "message": fields.String
}
c.定义资源
class GoodsResource(Resource):
    @marshal_with(single_goods_fields)
    def get(self, id):
        goods = Goods.query.get(id)
        print(goods)
        data = {"code": 200, "message": "success", "data": goods}
        return data

 访问:http://127.0.0.1:5000/goods/1/

结果:{"data": {"show_name": "apple", "price": 1.236, "uri": "http://127.0.0.1:5000/goods/1/"}, "code": 200, "message": "success"}

 d.列表展示
multi_goods_fields = {
    "data": fields.List(fields.Nested(goods_fields)),
    "code": fields.Integer,
    "message": fields.String
}


class GoodsListResource(Resource):
    # 方式3,数据嵌套
    @marshal_with(multi_goods_fields)
    def get(self):
        goods_list = Goods.query.all()
        return {"code": 200, "message": "success", "data": goods_list}

 访问:http://127.0.0.1:5000/goods/

结果:{"data": [{"show_name": "apple", "price": 1.236, "uri": "http://127.0.0.1:5000/goods/1/"}], "code": 200, "message": "success"}

 
自定义field字段:
class MyField(fields.Raw):
    def format(self, value):
        return "true" if value else "false"
    
    
goods_fields = {
    "show_name": fields.String(attribute='name'),
    "price": fields.Float,
    "status": MyField(attribute='status')
}

 

自定义错误信息:

class GoodsResource(Resource):
    @marshal_with(single_goods_fields)
    def get(self, id):
        goods = Goods.query.get(id)
        if True:
            from flask_restful import abort
            abort(400, message="not found gooooods")
        data = {"code": 200, "message": "success", "data": goods}
        return data

class GoodsResource(Resource):
    @marshal_with(single_goods_fields)
    def get(self, id):
        goods = Goods.query.get(id)
        if True:
            from flask_restful import abort
            abort(400, message="not found gooooods", code=500, data=None)
        data = {"code": 200, "message": "success", "data": goods}
        return data

 

 

 

 

posted on 2020-06-21 16:03  myworldworld  阅读(436)  评论(0)    收藏  举报

导航