Flask-restplus 返回 marshal 模型而不是数据
Flask-restplus returning marshal model instead of the data
所以我对实现 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) 时,作为响应,我得到了编组模型而不是数据本身。如果我打印数据,它会被打印出来,但由于网络中的某种原因,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。使用 marshal 装饰器:
{
"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": ""
}
}
如果有人能告诉我我做错了什么,那将非常有帮助,因为我需要将输出重新接收为没有装饰器的输出片段中显示的输出。
谢谢。
这是一张从上到下显示调用顺序的图表,以帮助理解正在发生的事情:
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
}
}
响应中的 message
和 code
嵌套在 data
.
中
您需要对数据进行适当的建模,以便能够对其进行编组。这可以通过传递参数来确定要在 marshal 字典中查找的字段。
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
字段中。
所以我对实现 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) 时,作为响应,我得到了编组模型而不是数据本身。如果我打印数据,它会被打印出来,但由于网络中的某种原因,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。使用 marshal 装饰器:
{
"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": ""
}
}
如果有人能告诉我我做错了什么,那将非常有帮助,因为我需要将输出重新接收为没有装饰器的输出片段中显示的输出。
谢谢。
这是一张从上到下显示调用顺序的图表,以帮助理解正在发生的事情:
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
}
}
响应中的 message
和 code
嵌套在 data
.
您需要对数据进行适当的建模,以便能够对其进行编组。这可以通过传递参数来确定要在 marshal 字典中查找的字段。
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
字段中。