【问题标题】:Flask-restplus returning marshal model instead of the dataFlask-restplus 返回元帅模型而不是数据
【发布时间】:2019-01-23 10:41:49
【问题描述】:

所以我对实施 flask-restplus 还是很陌生,我遇到了这个障碍。

我一遍又一遍地阅读了 restplus 文档,并遵循了几个示例。但我所面临的行为与应有的截然不同。

所以我有一个模型,它应该是另一个模型的对象列表(从函数drone_model() 返回)。

drones_list = api.model('drones_list', {
    'items': fields.List(fields.Nested(drone_model())),
    'message':fields.String(''),
    'code': fields.Integer('')

})

一切正常,没有错误。但是当我尝试 API (http://127.0.0.1:5000/datamine/v2/drones) 时,作为响应,我得到了 Marshalling 模型而不是数据本身。如果我打印数据,它会被打印出来,但由于某种原因在网络上,restplus 模型被返回。

下面是我编写的代码。如果我关闭了 marshal_with 装饰器,那么数据返回就好了。

@api.route('/')
class DronesList(Resource):

    @api.marshal_with(drones_list, envelope='data')
    @api.response(200, 'All drones successfully fetched!')
    def get(self):
        """
        Get all drones!.
        """
        from app.utils.common import get_start_end_date_from_request
        start_date, end_date = get_start_end_date_from_request(request)
        drones = []

        for drone in Drone.objects:
            drones.append({
                'id': str(drone.id),
                'serial_id': drone.serial_id,
                'maintenances': [],
                'status': get_dynamic_status(drone, start_date, end_date),
                'picture_url': drone.asset.picture_url,
                'manufacturer': drone.asset.manufacturer,
                'model_name': drone.asset.model_name,
                'drone_type': drone.asset.drone_type,
                'payload_type': drone.asset.payload_type,
                'asset_url': drone.get_url(drone.id)
            })
        success = ClientSuccessFunctionClass('All drones successfully fetched!', 200, drones)
        return (success.to_dict())

这些是浏览器上的输出:

1.没有元帅装饰器:

{
    "data": {
        "items": [
            {
                "id": "5aeafcb93a33683f73827e91",
                "serial_id": "Drone 1",
                "maintenances": [],
                "status": "Decommissioned",
                "picture_url": "some img url",
                "manufacturer": "DJI",
                "model_name": "Phantom 4 Pro",
                "drone_type": "Quadcopter",
                "payload_type": "RGB Camera",
                "asset_url": "http://127.0.0.1:5000/datamine/v1/drones/5aeafcb93a33683f73827e91"
            },
            {
                "id": "5aeaff374f85747f90df2714",
                "serial_id": "Drone 2",
                "maintenances": [],
                "status": "Available",
                "picture_url": "sime url",
                "manufacturer": "DJI",
                "model_name": "Phantom 4",
                "drone_type": "Quadcopter",
                "payload_type": "RGB Camera",
                "asset_url": "http://127.0.0.1:5000/datamine/v1/drones/5aeaff374f85747f90df2714"
            }
        ],
        "message": "All drones successfully fetched!",
        "code":200
    }
}

2。使用元帅装饰器:

{
    "data": {
        "items": [
            {
                "id": "Id of Drone",
                "serial_id": "Name of Drone",
                "status": "Status of Drone",
                "maintenances": null,
                "picture_url": "Picture URL",
                "manufacturer": "Manufacturer of Drone",
                "model_name": "Model name of Drone",
                "drone_type": "Type of Drone",
                "payload_type": "Payload type of Drone",
                "asset_url": "Asset URL of Drone"
            }
        ],
        "message": "",
        "code": ""
    }
}

如果有人能告诉我我做错了什么,那将非常有帮助,因为我需要在没有装饰器的情况下接收输出的 sn-p 中显示的输出。

谢谢。

【问题讨论】:

    标签: python flask-restplus


    【解决方案1】:

    这是一个从上到下显示调用顺序的图表,以帮助理解正在发生的事情:

    get() 
       → api.response(200, 'All drones successfully fetched!') # documents the response
          → api.marshal_with(drones_list, envelope='data')` # returns marshalled dict
    

    调用get 的结果被传递给api.response 装饰器函数,其结果被传递给api.marshal_with 装饰器函数。

    查看调用get()返回的字典的形状

    {
        data {
            items [
                {
                    id,
                    serial_id,
                    maintenances,
                    status,
                    picture_url,
                    manufacturer,
                    model_name,
                    drone_type,
                    payload_type,
                    asset_url
                }
            ],
            message,
            code
        }
    }
    

    响应中的messagecode 嵌套在data 内。

    您需要对数据进行适当的建模,以便能够对其进行编组。这可以通过传递在元帅字典中查找哪个字段的参数来完成。

    drones_list = api.model('drones_list', {
        'items': fields.List(fields.Nested(drone_model()), attribute='data.items'),
        'message':fields.String(attribute='data.message'),
        'code': fields.Integer(attribute='data.code')
    })
    

    如您所见,在视图上应用 api.marshal_with 装饰器函数是非常多余的,因为它只是取消嵌套然后将结果嵌套在 data 字段中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-11
      • 1970-01-01
      • 2016-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多