flask-marshmallow: как пометить все поля как необязательные, только если метод PUT
Я делаю колбу успокоительный API, с чем у меня проблемы это зефир-sqlalchemy, и вебарги
короче вот моя модель 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-classful и 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, некоторые поля не обнуляются, поэтому моя схема зефира помечает их как обязательные. мой get
, index
, delete
а также post
методы все работают отлично. Но я включил пост по одной причине:
например, когда я пытаюсь опубликовать нового пользователя без имени, возникает HTTP-код 422, потому что name
поле обязательно для заполнения, это то, что я хочу, и это сделано идеально.
НО при редактировании полей с put
запрос, я желаю, чтобы ВСЕ в моей схеме стало необязательным... прямо сейчас, если я хочу обновить пользователя, я должен предоставить не только идентификатор..., но ВСЕ другие данные, требуемые по умолчанию, даже если я их вообще не менял.
Короче говоря, как пометить все поля как "необязательные", когда метод "положен"?
РЕДАКТИРОВАТЬ: так же, как решение, предоставленное @Mekicha, я сделал следующие изменения:
измените схему, чтобы обязательные поля в моей модели приняли значение None. как это:
class UserSchema(ModelSchema):
class Meta:
model = User
...
name = fields.Str(missing=None, required=True)
email = fields.Email(missing=None, required=True)
...
Измените условие метода put и post из этого:
if kwargs[d] is not missing:
к этому:
if kwargs[d] is not missing and kwargs[d] is not None:
2 ответа
Поскольку вы хотите сделать поля необязательными во время put
как насчет настройки missing
атрибут для полей. Из документа:
отсутствует используется для десериализации, если поле не найдено во входных данных
Я думаю, что сочетание missing
а также allow_none
(который по умолчанию True
когда missing=None
), как указано здесь: https://github.com/marshmallow-code/marshmallow/blob/dev/marshmallow/fields.py должен работать для вас
Вы можете создать экземпляр схемы с помощьюpartial=True
чтобы сделать все поля необязательными.