Выравнивание вложенного поля в массив в Flask API - PullRequest
0 голосов
/ 22 февраля 2020

Я использую flask_restplus для создания API.

У меня есть две модели:

model_barcode = api.model('Barcode', {
        'code': fields.String,
    })

и

model_product = api.model('Product', {
        'id': fields.Integer,
        'name': fields.String,
        'barcodes': fields.Nested(model_barcode, as_list=True),
    })

Отношения между Product и Barcode - это число ко многим.

Ответ API выглядит следующим образом:

[
    {
        "id": 15707,
        "name": "Jojo Leaf Eater - White",
        "barcodes": [
            {
                "code": "6009702666853"
            },
            {
                "code": "9317118010229"
            },
            {
                "code": "6009194082315"
            },
            {
                "code": "6009149569649"
            }
        ]
    }
]

Однако, поскольку содержимое модели штрих-кода представляет собой только одно поле, которое я хочу вместо этого он выглядит следующим образом:

[
    {
        "id": 15707,
        "name": "Jojo Leaf Eater - White",
        "barcodes": ["6009702666853", "9317118010229",
                     "6009194082315", "6009149569649"]
    }
]

Как бы я это сделал?

Я пытался перевести вызов на fields.Nested() в fields.List(), но это не помогло.

Если у кого-то есть идея, как сделать эту работу, я бы очень признателен за помощь!

Спасибо.

Справочная информация

Вот соответствующие версии пакета:

Flask==1.1.1
flask-restplus==0.13.0
marshmallow==3.3.0
SQLAlchemy==1.3.11
simplejson==3.17.0

Классы базы данных

Вот определения классов SQLAlchemy:

class Product(Base):
    __tablename__ = 'product'

    id                  = Column(Integer, primary_key=True)
    name                = Column(String(256))
    barcodes            = relationship('Barcode',
                                       secondary='product_barcode',
                                       back_populates='products')

class Barcode(Base):
    __tablename__ = 'barcode'

    id                  = Column(Integer, primary_key=True)
    code                = Column(String(15))
    products            = relationship('Product',
                                       secondary='product_barcode',
                                       back_populates='barcodes')

Альтернативная реализация

У меня есть рабочая реализация, использующая зефир.

from marshmallow import Schema, fields

class BarcodeSchema(Schema):
    class Meta:
        fields = ('id', 'code',)

class ProductDetailSchema(Schema):
    barcodes = fields.Pluck(BarcodeSchema, "code", many=True)
    class Meta:
        fields = ('id', 'name', 'barcodes')
        ordered = False

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

1 Ответ

0 голосов
/ 18 апреля 2020

Вы могли бы сделать это легко, как это

'barcodes': fields.List(fields.String, attribute=lambda p: [product.code for product in p.barcodes])
...