Как выполнить обновление частично во Flask? - PullRequest
0 голосов
/ 03 апреля 2019

Есть ли способ обновить метод PUT при перезапуске колбы с частично полями?

в настоящее время мой метод PUT выполняет это, однако, если поля, которых там нет, выдают ошибку.

item = ItemModel.find_by_id(id)
    item_json = request.get_json()

    if(item):
        item.name = item_json['name']
        item.code = item_json['code']
        item.tags = item_json['tags']
    else:
        try:
            item = item_schema.load(
                item_json
            )
         except ValidationError as err:
            return err.messages, HTTPStatus.BAD_REQUEST

    item.save_to_db()
    return {'message': item_schema.dump(item)}, HTTPStatus.OK

Ответы [ 2 ]

0 голосов
/ 04 апреля 2019

Вот что я делаю:

  • Используйте метод POST для создания нового элемента и метод PUT для обновления элемента.

  • Используйте зефир Schema, чтобы сначала проверить данные при получении запросов. Для этого вы можете использовать webargs . Он поддерживается командой разработчиков зефира. Выдает соответствующую ошибку HTTP (400, если запрос искажен, и 422, если это правильный json, но не проходит проверку).

  • Универсального правила для PUT не существует. С точки зрения ресурса, PUT для элемента предназначен для замены всего элемента (в отличие от PATCH). Это не означает, что он предназначен для замены всего элемента в базе данных, поскольку могут существовать поля, которые пользователь не может изменить (идентификатор, create_at, updated_at или некоторые другие поля, которые могут быть представлены в другом ресурсе, это действительно зависит ). Метод update_to_db в вашем ответе выглядит отлично.

Обратите внимание, что вы все равно должны обнаруживать потенциальные ошибки при записи в базу данных (ошибка подключения к базе данных, элемент не найден, ошибка целостности (недопустимый внешний ключ), ...), но по крайней мере проверка выполняется как можно скорее.

0 голосов
/ 03 апреля 2019

Я нашел способ, но не уверен, что это лучший способ или нет.Таким образом, идея в том, что мы создаем новую функцию в модели для обновления и передачи объекта JSON и установки атрибута с помощью объекта.

from . import db


class ItemModel(db.Model):
    __tablename__ = "items"

    id = db.Column(db.Integer, primary_key=True)
    code = db.Column(db.String(), nullable=False)
    name = db.Column(db.String(), nullable=False)
    tags = db.Column(db.String(), nullable=False)
    created_at = db.Column(db.DateTime, server_default=db.func.now())
    updated_at = db.Column(
        db.DateTime,
        server_default=db.func.now(),
        server_onupdate=db.func.now()
    )

    def update_to_db(self, data):
        for key, value in data.items():
            setattr(self, key, value)
        db.session.commit()

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

@classmethod
def put(self, id: int):
    item = ItemModel.find_by_id(id)

    if(item):
        try:
            item.update_to_db(
                request.get_json()
            )
        except ValidationError as err:
            return err.messages, HTTPStatus.BAD_REQUEST

        return {'message': item_schema.dump(item)}, HTTPStatus.OK

    return {'message': gettext('item_not_found')}, HTTPStatus.NOT_FOUND

Это работает, но все еще не уверен, есть ли лучший способ сделать это.

...