Elfayer
Elfayer

Reputation: 4571

How to marshal nested attribute up to the schema?

I have a project with articles having different prices depending on their location.

The Article and ArticlePrice models are as follow:

from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import relationship

db = SQLAlchemy()

class Article(db.Model):
    __tablename__ = 'article'

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(255), nullable=False)
    description = db.Column(db.Text)
    prices = relationship("ArticlePrice")

class ArticlePrice(db.Model):
    __tablename__ = 'article_prices'

    id = db.Column(db.Integer, primary_key=True)
    article_id = db.Column(db.Integer, db.ForeignKey("article.id"), nullable=False)
    location_id = db.Column(db.Integer, db.ForeignKey("location.id"), nullable=False)
    price = db.Column(db.Integer, nullable=False)
    location = relationship('Location')

I don't want to return all the prices of an article to the client but just his location price. Such as he receives a JSON like:

{
  id: '',
  title: '',
  description: '',
  price: 0
}

So my schema looks like this now:

article = namespace.model('Article', {
    'id': fields.Integer(required=True),
    'title': fields.String(required=True),
    'description': fields.String(required=True),
    'price': fields.Integer(attribute=lambda x: x.prices[0].price), # This one works
})

This is working fine with a lambda expression, but in the documentation (flask-restful and flask-restplus) they talk about another way, but I can't make it work as follow:

'price': fields.Integer(attribute='prices[0].price') # This one doesn't work

What am I missing? Why is the last syntax not working? Did I misunderstand this syntax use?

Upvotes: 2

Views: 1418

Answers (1)

Alexander
Alexander

Reputation: 7842

Here is an example from the documentation (http://flask-restplus.readthedocs.io/en/stable/marshalling.html#renaming-attributes):

model = {
    'name': fields.String(attribute='people_list.0.person_dictionary.name'),
    'address': fields.String,
}

So just replace [0] by .0.

Upvotes: 1

Related Questions