Open datawookie opened 4 years ago
I asked this question on StackOverflow (here) but didn't get any help there. I'm sure that there is a simple answer to this.
I'm using flask_restplus to build an API.
flask_restplus
I have two models:
model_barcode = api.model('Barcode', { 'code': fields.String, })
and
model_product = api.model('Product', { 'id': fields.Integer, 'name': fields.String, 'barcodes': fields.Nested(model_barcode, as_list=True), })
The relationship between Product and Barcode is many-to-many.
Product
Barcode
The API response looks like this:
[ { "id": 15707, "name": "Jojo Leaf Eater - White", "barcodes": [ { "code": "6009702666853" }, { "code": "9317118010229" }, { "code": "6009194082315" }, { "code": "6009149569649" } ] } ]
However, since the contents of the barcode model are just a single field I want it to marshal like this instead:
[ { "id": 15707, "name": "Jojo Leaf Eater - White", "barcodes": ["6009702666853", "9317118010229", "6009194082315", "6009149569649"] } ]
How would I do this?
I've tried wrapping the call to fields.Nested() in fields.List() but that did not help.
fields.Nested()
fields.List()
If anybody has an idea of how to make this work, I'd really appreciate the help!
Thanks.
Background Information
Here are the relevant package versions:
Flask==1.1.1 flask-restplus==0.13.0 marshmallow==3.3.0 SQLAlchemy==1.3.11 simplejson==3.17.0
Database Classes
Here are the definitions of the SQLAlchemy classes:
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')
Alternative Implementation
I have a working implementation using Marshmallow.
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
This does precisely what I want. However I'd really prefer to use flask_restplus models because they make the code for the actual API a lot neater.
Though late to the party but you could have done it easliy like this 'barcodes': fields.List(fields.String, attribute=lambda p: [product.code for product in p.barcodes])
'barcodes': fields.List(fields.String, attribute=lambda p: [product.code for product in p.barcodes])
I asked this question on StackOverflow (here) but didn't get any help there. I'm sure that there is a simple answer to this.
I'm using
flask_restplus
to build an API.I have two models:
and
The relationship between
Product
andBarcode
is many-to-many.The API response looks like this:
However, since the contents of the barcode model are just a single field I want it to marshal like this instead:
How would I do this?
I've tried wrapping the call to
fields.Nested()
infields.List()
but that did not help.If anybody has an idea of how to make this work, I'd really appreciate the help!
Thanks.
Background Information
Here are the relevant package versions:
Database Classes
Here are the definitions of the SQLAlchemy classes:
Alternative Implementation
I have a working implementation using Marshmallow.
This does precisely what I want. However I'd really prefer to use
flask_restplus
models because they make the code for the actual API a lot neater.