gpt4 book ai didi

python - flask /WTF/SQLAlchemy : using QuerySelectMultipleField with Form. populate_obj()

转载 作者:行者123 更新时间:2023-11-28 19:15:26 25 4
gpt4 key购买 nike

我有一个包含 QuerySelectMultipleField 的表单(通过 Flask-WTF 的 WTForms),如下所示:

class EditDocumentForm(Form):
# other fields omitted for brevity
users = QuerySelectMultipleField('Select Users',
query_factory=User.query.all,
get_label=lambda u: u.username)

效果很好——我只需实例化表单并将其传递到我的模板进行渲染,所有正确的选择都在那里。

但是,当我 POST 表单并尝试使用 Form.populate_obj() 吸收数据时,我从 SQLAlchemy 收到一条愤怒的消息:

InvalidRequestError: Object '<User at 0x10a4d33d0>' is already attached to session '1' (this is '3')

View 函数:

@app.route("/document/edit/<doc_id>", methods=['GET', 'POST'])
@login_required
def edit_document(doc_id):
doc = Document.query.filter_by(id=doc_id).first()
if (doc is not None) and (doc.user_id == current_user.id):
form = EditDocumentForm(obj=doc)
if request.method == "POST":
if form.validate():
form.populate_obj(doc)
db.session.commit()
return redirect('/')
else:
_flash_validation_errors(form)
return render_template("edit.html", form=form)
flash("The document you requested doesn't exist, or you don't have permission to access it.", "error")
return(redirect('/'))

看起来好像在创建表单时使用了一个 session ,在我尝试填充模型对象时使用了另一个 session 。这一切都在幕后发生,因为我依靠 Flask-SQLAlchemy 为我完成所有 session 工作。

Document模型中,user字段是这样声明的:

users = db.relationship('User',
secondary=shares,
backref=db.backref('shared_docs', lazy='dynamic'))

(对于多对多关系,shares 当然是 SQLAlchemy.table 的一个实例)。

那么:我是不是做错了什么,或者是 Form.populate_obj() 出了问题,或者我可以责怪外星人?让我换个说法:我做错了什么?

编辑

解决方法 this answer似乎解决了这个问题,即通过导入我的 SQLAlchemy 对象并显式使用它的 session 来更改我的 query_factory:

query_factory=lambda: db.session.query(User)

不过,我不得不说,这对我来说有一种奇怪的气味。这真的是最好的处理方式吗?

最佳答案

这完全取决于您的模型类如何绑定(bind)到 session 。我的猜测是:您没有使用 Flask-SQLAlchemy 提供的基类:db.Model 用于您的 DocumentUser 模型?

如您的“编辑”所述,不使用Userquery 方法,而是使用db.session.query相反,您强制 populate_obj 使用稍后将通过 db.session.commit 调用提交的同一 session 。也就是说,您在执行 Document.query.filter_by 时可能仍在使用另一个 session ,这很可能意味着您仍在使用 2 个数据库连接并可以将其减少为一个。

总的来说,我建议你不要在你的模型上使用query方法(但那是因为我不喜欢神奇的东西;)),确保使用 Flask-SQLAlchemy 的 db.Model 如果可以的话,深入阅读你使用的框架/库是如何工作的,因为这是一个很好的习惯,不会花费很多时间,并且可以显着提高质量和代码的可维护性。

关于python - flask /WTF/SQLAlchemy : using QuerySelectMultipleField with Form. populate_obj(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34091333/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com