首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >烧瓶管理-使用on_model_change()访问旧值

烧瓶管理-使用on_model_change()访问旧值
EN

Stack Overflow用户
提问于 2020-03-23 23:28:01
回答 1查看 1.1K关注 0票数 1

我的目标是在用户更改现有记录的值时执行一些附加操作。

我找到了on_model_change() 在医生里并编写了以下代码:

代码语言:javascript
运行
复制
def on_model_change(self, form, model, is_created):
    # get old and new value
    old_name = model.name
    new_name = form.name

    if new_name != old_name:
        # if the value is changed perform some other action 
        rename_files(new_name)

我的期望是,在应用表单的新值之前,model参数将表示记录。但事实并非如此。相反,我发现model的值总是与form相同,这意味着if语句从未实现。

后来我试了一下:

代码语言:javascript
运行
复制
class MyView(ModelView):
    # excluding the name field from the form
    form_excluded_columns = ('name')

    form_extra_fields = {
        # and adding a set_name field instead
        'set_name':StringField('Name')
    }
    ...
代码语言:javascript
运行
复制
def on_model_change(self, form, model, is_created):
    # getting the new value from set_name instead of name 
    new_name = form.set_name
    ...

虽然这解决了我的目标,但也引起了一个问题:

set_name字段不会预先填充现有名称,即使不打算更改名称,也会迫使用户键入名称。

我还尝试在db.rollback()开始时执行on_model_change(),这将撤消烧瓶管理所做的所有更改,并使model表示旧数据。这是相当麻烦,并导致我的重新实现了很多烧瓶管理代码,这变得很混乱。

解决这个问题的最好办法是什么?

我如何解决IT

我使用on_form_prefill预先填充了新的name字段,而不是@pjcunningham的答案。

代码语言:javascript
运行
复制
# fill values from model 
def on_form_prefill(self, form, id):
    # get track model
    track = Tracks.query.filter_by(id=id).first()

    # fill new values
    form.set_name.data = track.name
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-24 11:16:43

重写视图中的方法模型。这里是默认行为,如果您使用SqlAlchemy视图,我添加了一些注释来解释模型的状态。

代码语言:javascript
运行
复制
def update_model(self, form, model):
    """
        Update model from form.
        :param form:
            Form instance
        :param model:
            Model instance
    """
    try:
        # at this point model variable has the unmodified values

        form.populate_obj(model)

        # at this point model variable has the form values

        # your on_model_change is called
        self._on_model_change(form, model, False)

        # model is now being committed
        self.session.commit()
    except Exception as ex:
        if not self.handle_view_exception(ex):
            flash(gettext('Failed to update record. %(error)s', error=str(ex)), 'error')
            log.exception('Failed to update record.')

        self.session.rollback()

        return False
    else:
        # model is now committed to the database
        self.after_model_change(form, model, False)

    return True

您可能需要下面这样的内容,这取决于您将支票放在哪里,在模型提交之后,我已经将其放在哪里:

代码语言:javascript
运行
复制
def update_model(self, form, model):
    """
        Update model from form.
        :param form:
            Form instance
        :param model:
            Model instance
    """
    try:

        old_name = model.name
        new_name = form.name.data

        # continue processing the form

        form.populate_obj(model)
        self._on_model_change(form, model, False)
        self.session.commit()
    except Exception as ex:
        if not self.handle_view_exception(ex):
            flash(gettext('Failed to update record. %(error)s', error=str(ex)), 'error')
            log.exception('Failed to update record.')

        self.session.rollback()

        return False
    else:

        # the model got committed now run our check:
        if new_name != old_name:
            # if the value is changed perform some other action
            rename_files(new_name)

        self.after_model_change(form, model, False)

    return True

对于模型模型,也可以使用类似的方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60822953

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档