Можно ли использовать схему для настраиваемого поля зефира?

Допустим, у меня есть UserSchema:

class UserSchema(ma.ModelSchema):
    class Meta:
        model = User
        fields = ('email', 'fullname')

и у меня есть еще одна объектная модель Group, которая имеет отношение «многие ко многим» с User и метод для возврата подмножества своих пользователей:

class Group(db.Model):
    ...


    def get_active_members(self):
        active_members = ...
        return active_members 

Теперь я пытаюсь написать схему зефира для сериализации модели Group, включая активные члены.

Я знаю, что могу использовать настраиваемое поле, но если я делать:

class GroupSchema(ma.ModelSchema):
    members = fields.Function(lambda obj: obj.get_active_members())

Я получаю сообщение об ошибке, говорящее мне, что объект User не сериализуем

TypeError: объект типа «Пользователь» не сериализуем JSON

Если я попытаюсь использовать вместо этого вложенное поле, оно просто ничего не вернет так как get_active_members не является полем.

Есть ли способ вернуть активных членов в этом случае?

Возможное решение, которое я нашел:

class Group(db.Model):
    ...

    @property
    def members(self):
        return get_active_members()

    def get_active_members(self):
        active_members = ...
        return active_members 

class GroupSchema(ma.ModelSchema):
    members = fields.Nested(UserSchema, dump_only=True)

Но я не совсем уверен, что Marshmallow должен работать именно так.


person heapOverflow    schedule 12.04.2018    source источник


Ответы (1)


Я не знаю, как/что именно вы пытаетесь сериализовать, но распространенная ошибка, которую я вижу, люди делают со схемой Marshmallow, заключается в сериализации самой схемы, забывая, что схема не содержит данных, и, следовательно, ее сериализация дает ошибку. Вот пример вложенной схемы:

from marshmallow import *

class UserSchema(Schema):
    class Meta:
        fields = ('email', 'fullname')

class GroupSchema(Schema):
    users = fields.Nested(UserSchema, many=True)

Итак, чтобы сериализовать данные с помощью этой схемы, я бы сделал:

data = {"users": [{"fullname": "Mr. Bean", "email": "[email protected]"}, {"fullname": "James Bond", "email": "[email protected]"}]}

schema = GroupSchema()
schema.dumps(data)

Который дает

MarshalResult(data='{"users": [{"email": "[email protected]", "fullname": "Mr. Bean"}, {"email": "[email protected]", "fullname": "James Bond"}]}', errors={})
person PoP    schedule 13.04.2018
comment
Моя проблема в том, что у меня нет атрибута пользователей в модели группы. У меня есть только метод, который дает мне список активных членов. - person heapOverflow; 13.04.2018