我正在使用flask-marshmallow(marshmallow = v3.0.0rc1,flask-marshmallow = 0.9.0)和flask-sqlalchemy(sqlalchemy = 1.2.16,flask-sqlalchemy = 2.3.2)

我有这个模型和架构。

from marshmallow import post_load, fields
from .datastore import sqla_database as db
from .extensions import marshmallow as ma

class Study(db.Model):
    _id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String, nullable=False)

    tests = db.relationship("Test", backref="study", lazy='select', cascade="all, delete-orphan")

    @property
    def test_count(self):
        return len(self.tests)

class StudySchema(ma.ModelSchema):
    test_count = fields.Integer(dump_only=True)
    class Meta:
        model = Study
        sqla_session = db.session

schema = StudySchema()
payload = request.get_json()
schema.load(data=payload, instance=Study.query.get(payload["_id"]))
schema.session.commit()

如果我使用此有效负载执行PUT操作{'_id': 1, 'name': 'Study1', 'test_count': 0}我得到以下异常marshmallow.exceptions.ValidationError: {'test_count': ['Unknown field.']}
如果我删除dump_only=True,我会得到这个异常AttributeError: can't set attribute,这对我来说很有意义,因为它试图在模型类上设置不带setter方法的test_count。

我不明白的是为什么dump_only不忽略该属性。当棉花糖标记为dump_only时,为什么棉花糖仍在尝试验证和理解此字段?

最佳答案

在棉花糖2中,未知或dump_only字段将从输入中忽略。除非用户决定在错误上添加自己的验证。

在棉花糖3中,我们将其更改为提供三种可能性(请参阅docs):

  • RAISE(默认)
  • EXCLUDE(如棉花糖2)
  • INCLUDE(不通过验证即可传递数据)

  • 已经进行了有关如何处理dump_only字段的讨论,我们得出的结论是,从客户端的角度来看,应该将这些字段视为未知字段(请参阅https://github.com/marshmallow-code/marshmallow/issues/875)。

    最重要的是,您的PUT有效负载不应包含dump_only字段。或者,您可以将EXCLUDE策略设置为您的架构,但是我更喜欢前一个选项。

    10-06 10:30