Flask-restplus возвращает данные маршала вместо данных - PullRequest
0 голосов
/ 23 января 2019

Итак, я довольно новичок в реализации 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. С маршалом-декоратором:

{
    "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": ""
    }
}

Было бы очень полезно, если бы кто-то мог сказать мне, что я делаю неправильно, поскольку мне нужно получить вывод, как показано в фрагменте вывода без декоратора.

Спасибо.

1 Ответ

0 голосов
/ 23 января 2019

Вот диаграмма, показывающая порядок вызовов сверху вниз, чтобы помочь понять, что происходит:

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.

Вам необходимо смоделировать данные соответствующим образом, чтобы иметь возможность их упорядочить.Это можно сделать, передав аргумент для того, какое поле искать в словаре маршала.

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 к представлению довольно избыточно, учитывая, что оно толькоunnests затем вкладывает результат в поле data.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...