在Flask中SQLAlchemy merge()不起作用

0 投票
2 回答
1716 浏览
提问于 2025-04-17 14:17

我正在学习如何使用sqlalchemy,并且正在开发一个小应用。现在我在用ORM更新数据库中的数据时遇到了一些问题。我不太确定我哪里出了错。虽然表单edit_product.html能正确显示数据,但在执行return redirect(url_for这条语句时,数据并没有被更新。我使用了merge()方法,也尝试过一些教程中建议的add(),但这样做时却出现了记录已经存在的错误。

这是我在views.py中的edit_product函数:

from database import db_session
@app.route('/product/edit/<int:product_id>', methods=['GET', 'POST'])
def edit_product(product_id):
    product = Product.query.filter(Product.id == product_id).first()
    form = NewOtrosForm(obj=product)
    if request.method == 'POST':
        print request.form
        if form.validate():
            form.populate_obj(product)
            db_session.commit()
        return redirect(url_for('product'))
    else:
        return render_template('edit_product.html', form=form)

这是我在jinja2模板中的编辑表单内容:

{% from "_formhelpers.html" import render_field %}
    <form method=post action="">
        <dl>
            {{ render_field(form.name) }}
            {{ render_field(form.price) }}
            {{ render_field(form.description) }}
            {{ render_field(form.provider) }}
            {{ render_field(form.detalles) }}
        </dl>
        <p><input type="submit" value="Save Changes"></p>
    </form>

2 个回答

1

你在这里不需要使用 merge() 方法。这个方法的作用是把外部对象的状态转移到一个新的或者已经存在的会话实例中。你的 product 对象已经在这个会话里了,所以只需要调用 form.populate_obj(product)(对 product 的修改会让它在这个会话中标记为“脏”状态),然后再执行 db_session.commit() 就可以了。

1

你能试着把下面的内容从:

form = NewOtrosForm(obj=product)

改成:

form = NewOtrosForm(request.form, obj=product)

撰写回答