Flask Marshmallow сериализует связь многих со многими с дополнительным полем - PullRequest
1 голос
/ 15 октября 2019

У меня есть проблема в приложении Flask с объектом модели сериализации, который имеет отношение многие ко многим с дополнительным полем, хранящимся в таблице ассоциации. Я хотел бы, чтобы сериализованные данные выглядели так:

{
    "id": "123",
    "name": "name",
    "mobile": "phone number",
    "interest": [1, 2, 3]
    "_embedded": {
        "interest": [
            {
                "id": 1,
                "name": "ECONOMIC",
                "active": true,
            },
            {
                "id": 2,
                "name": "POETRY",
                "active": true,
            },
            {
                "id": 3,
                "name": "SPORT",
                "active": false,
            },
        ]
    }
}

На данный момент мне удалось подготовить необходимые модели, как показано ниже:

class OwnerInterests(db.Model):
    owner_id = db.Column(db.Integer, db.ForeignKey('owners.id'), primary_key=True)
    interest_id = db.Column(db.Integer, db.ForeignKey('interests.id'), primary_key=True)
    active = db.Column(db.Boolean)
    interest = db.relationship('Interests', back_populates='owners')
    owner = db.relationship('Owners', back_populates='interests')


class Owners(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    mobile = db.Column(db.String)
    interests = db.relationship('OwnersInterests', back_populates='owner')


class Interests(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    owners = db.relationship('OwnersInterests', back_populates='interest')

, но теперь я задаюсь вопросом о подходеКак подготовить sqlalchemy запрос с помощью схемы зефира. Есть мысли?

РЕДАКТИРОВАТЬ:

Моя текущая схема зефир выглядит так:

class InterestSchema(ma.ModelSchema):
    class Meta:
        model = Interests
        exclude = ('owners',)


class OwnerSchema(ma.ModelSchema):
    interests = ma.Nested(InterestSchema, many=True)

    class Meta:
        model = Owners

1 Ответ

0 голосов
/ 31 октября 2019

Эта схема дает вам нечто, очень похожее на вашу спецификацию:

from marshmallow import Schema, fields


class InterestSchema(Schema):
    class Meta:
        fields = ('id', 'name')
        ordered = True


class OwnerInterestSchema(Schema):
    interest = fields.Nested(InterestSchema)

    class Meta:
        fields = ('id', 'interest', 'active')
        ordered = True


class OwnerSchema(Schema):
    interests = fields.Nested(OwnerInterestSchema, many=True)

    class Meta:
        fields = ('id', 'name', 'mobile', 'interests')
        ordered = True

Затем вы можете сериализовать ваши данные следующим образом (обратите внимание, что моя модель не имеет точно такое же имя, как у вас):

>>> from app.serialisation import OwnerSchema
>>> from app.models import Owner
>>> data = OwnerSchema().dump(Owner.query.get(1))
>>> from marshmallow import pprint
>>> pprint(data)
{"id": 1, "name": "John", "mobile": "07123456789", "interests": [{"interest": {"id": 1, "name": "Economics"}, "active": true}, {"interest": {"id": 2, "name": "Poetry"}, "active": true}, {"interest": {"id": 3, "name": "Sport"}, "active": false}]}

Позвольте мне сделать отступ в этом выводе, чтобы вы могли видеть, что происходит:

{
  "id": 1,
  "name": "John",
  "mobile": "07123456789",
  "interests": [
    {
      "interest": {
        "id": 1,
        "name": "Economics"
      },
      "active": true
    },
    {
      "interest": {
        "id": 2,
        "name": "Poetry"
      },
      "active": true
    },
    {
      "interest": {
        "id": 3,
        "name": "Sport"
      },
      "active": false
    }
  ]
}

Вы можете адаптировать его для использования парадигмы модель плюс-исключение, если хотите. И если вам действительно нужно это поле "_embedded" в вашем JSON, вам, вероятно, понадобится настраиваемое поле, как описано здесь .

Вы также можете использовать настраиваемые поля, чтобы сгладить ваши интересы и поместить"active" поле на том же уровне, что и "id" и "name", но я думаю, что это вводит в заблуждение.

...