flask-marshmallow:如何仅在方法为 PUT 时将所有字段标记为可选



我正在制作一个烧瓶休息的API,我遇到的问题是棉花糖-sqlalchemy和webargs。

简而言之,这是我的 sqlalchemy 模型:

class User(Model):
id = Column(String, primary_key=True)
name = Column(String(64), nullable=False)
email = Column(String(120), nullable=False)
password = Column(String(128))
creation_date = Column(DateTime, default=datetime.utcnow)

这是我的架构:

class UserSchema(ModelSchema):
class Meta:
model = User
strict = True
sqla_session = db.session
user_schema = UserSchema()

以及我使用 flask-class 和 webargs 的路线示例:

class UserView(FlaskView):
trailing_slash = False
model = User
schema = user_schema
@use_kwargs(schema.fields)
def post(self, **kwargs):
try:
entity = self.model()
for d in kwargs:
if kwargs[d] is not missing:
entity.__setattr__(d, kwargs[d])

db.session.add(entity)
db.session.commit()
o = self.schema.dump(entity).data
return jsonify({'{}'.format(self.model.__table__.name): o})
except IntegrityError:
return jsonify({'message': '{} exist in the database. choose another id'
.format(self.model.__table__.name)}), 409

@use_kwargs(schema.fields)
def put(self, id, **kwargs):
entity = self.model.query.filter_by(id=id).first_or_404()
for d in kwargs:
if kwargs[d] is not missing:
entity.__setattr__(d, kwargs[d])
db.session.commit()
o = self.schema.dump(entity).data
return jsonify({'{}'.format(self.model.__table__.name): o})
UserView.register(app)

问题:
正如你在我的sqlalchemy模型中看到的那样,有些字段不可为空,因此我的棉花糖schemda将它们标记为必需。我的getindexdeletepost方法都完美无缺。但我包括帖子的原因只有一个:

例如,当我尝试发布一个没有名称的新用户时,会引发 422 http 代码name因为字段是必需的,这是我想要的,而且做得很完美。

但是当使用put请求编辑字段时,我希望我的架构中的所有内容都成为可选的..现在,如果我想更新用户,我不仅必须提供id..,而且必须提供默认所需的所有其他信息,即使我根本没有更改它们。

简而言之,当方法被"放置"时,如何将所有字段标记为"可选"?

编辑:就像@Mekicha提供的解决方案一样,我进行了以下更改:

更改架构以使模型中的必填字段接受值 None。 像这样:

class UserSchema(ModelSchema):
class Meta:
model = User
...
name = fields.Str(missing=None, required=True)
email = fields.Email(missing=None, required=True)
...

从这里更改我的放置和发布方法条件:

if kwargs[d] is not missing:

对此:

if kwargs[d] is not missing and kwargs[d] is not None:

既然你想在put期间使字段可选,那么如何设置字段的missing属性。从文档中:

missing 用于反序列化(如果在 输入数据

我认为missingallow_none的组合(默认为missing=NoneTrue(,如此处指出:https://github.com/marshmallow-code/marshmallow/blob/dev/src/marshmallow/fields.py#L89 应该适合您

您可以使用partial=True实例化架构,以使所有字段都可选。

最新更新