Flask Marshmallow 序列化具有额外字段的多对多关系 [英] Flask Marshmallow serialize many to many relation with extra field
问题描述
我在 Flask 应用程序中遇到了序列化模型对象的问题,该对象与关联表中存储的额外字段存在多对多关系.我想要一个像这样的序列化数据:
<代码>{"id": "123","name": "姓名",手机号码",兴趣":[1, 2, 3]_嵌入":{兴趣": [{身份证":1,"name": "经济",活动":真实,},{身份证":2,"name": "诗歌",活动":真实,},{身份证":3,"name": "运动",活动":假,},]}}
现在我设法准备了一个必要的模型,如下所示:
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)活动 = db.Column(db.Boolean)兴趣 = db.relationship('兴趣', back_populates='owners')owner = db.relationship('Owners', back_populates='interests')类所有者(db.Model):id = db.Column(db.Integer, primary_key=True)名称 = db.Column(db.String)移动 = db.Column(db.String)兴趣 = db.relationship('OwnersInterests', back_populates='owner')类兴趣(db.Model):id = db.Column(db.Integer, primary_key=True)名称 = db.Column(db.String)所有者 = db.relationship('OwnersInterests', back_populates='interest')
但现在我想知道如何使用棉花糖模式准备 sqlalchemy 查询.有什么想法吗?
我当前的棉花糖架构如下:
class InterestSchema(ma.ModelSchema):元类:模型 = 兴趣exclude = ('所有者',)类 OwnerSchema(ma.ModelSchema):兴趣 = ma.Nested(InterestSchema, many=True)元类:模型 = 所有者
此架构为您提供与您的规范非常相似的内容:
from marshmallow import Schema, fields类 InterestSchema(架构):元类:字段 = ('id', 'name')有序 = 真类 OwnerInterestSchema(Schema):兴趣 = fields.Nested(InterestSchema)元类:字段 = ('id', 'interest', 'active')有序 = 真类所有者架构(架构):兴趣 = fields.Nested(OwnerInterestSchema, many=True)元类:字段 = ('id', 'name', 'mobile', 'interests')有序 = 真
然后您可以像这样序列化您的数据(请注意,我的模型与您的名称不完全相同):
<预><代码>>>>从 app.serialisation 导入 OwnerSchema>>>从 app.models 导入所有者>>>数据 = OwnerSchema().dump(Owner.query.get(1))>>>从棉花糖进口 pprint>>>打印(数据){"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":运动"},活动":假}]}让我缩进那个输出,这样你就可以看到发生了什么:
<代码>{身份证":1,"name": "约翰","手机": "07123456789",利益":[{兴趣": {身份证":1,"name": "经济学"},活动":真实},{兴趣": {身份证":2,"name": "诗"},活动":真实},{兴趣": {身份证":3,名称":运动"},活动":假}]}
如果需要,您可以调整它以使用模型加排除范式.如果你真的想要在你的 JSON 中使用 "_embedded"
字段,你可能需要一个自定义字段,如 此处.
您还可以使用自定义字段来扁平化您的兴趣,并将 "active"
字段与 "id"
和 "name"<放在同一级别/code>,但我认为这会产生误导.
I have an issue in Flask application with serialization model object that has a many to many relationship with extra field stored in association table. I would like to have a serialized data looking like so:
{
"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,
},
]
}
}
For now I managed to prepare a neccessary models as below:
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')
but now I'm wondering about approach, how to prepare a sqlalchemy query with marshmallow schema. Any thoughts?
EDIT :
My current marshmallow schema looks like:
class InterestSchema(ma.ModelSchema):
class Meta:
model = Interests
exclude = ('owners',)
class OwnerSchema(ma.ModelSchema):
interests = ma.Nested(InterestSchema, many=True)
class Meta:
model = Owners
This schema gives you something quite similar to your specification:
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
You can then serialise your data like this (note that my model doesn't have exactly the same name as yours):
>>> 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}]}
Let me just indent that output so you can see what's going on:
{
"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
}
]
}
You can adapt this to use the model-plus-exclude paradigm if you want. And if you really want that "_embedded"
field in your JSON, you probably need a custom field, as described here.
You could also use custom fields to flatten your interests and put the "active"
field on the same level as "id"
and "name"
, but I think that would be misleading.
这篇关于Flask Marshmallow 序列化具有额外字段的多对多关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!