Flask-SQLAlchemy InvalidRequestError:对象已附加到会话

时间:2013-05-13 19:27:28

标签: flask flask-sqlalchemy

我正在使用Flask创建一个论坛项目,并使用Flask-SQLAlchemy管理所有用户,线程,帖子等。但是,我发现当我尝试执行x(例如编辑帖子)时,如果我尝试执行其他任何操作(例如删除帖子),我会收到InvalidRequestError。

编辑帖子

def post_edit(id, t_id, p_id):
  post = Post.query.filter_by(id=p_id).first()
  if post.author.username == g.user.username:
    form = PostForm(body=post.body)
    if form.validate_on_submit():
      post.body = form.body.data
      db.session.commit()
      return redirect(url_for('thread', id=id, t_id=t_id))
    return render_template('post_edit.html', form=form, title='Edit')
  else:
    flash('Access denied.')
    return redirect(url_for('thread', id=id, t_id=t_id))

并删除帖子,

@app.route('/forum=<id>/thr=<t_id>/p=<p_id>/delete', methods=['GET','POST'])
def post_delete(id, t_id, p_id):
  post = Post.query.filter_by(id=p_id).first()
  if post.author.username == g.user.username:
    db.session.delete(post)
    db.session.commit()
    return redirect(url_for('thread', id=id, t_id=t_id))
  else:
    flash('Access denied.')
    return redirect(url_for('thread', id=id, t_id=t_id))

并发帖子

@app.route('/forum/id=<id>/thr=<t_id>', methods=['GET','POST'])
def thread(id, t_id):
  forum = Forum.query.filter_by(id=id).first()
  thread = Thread.query.filter_by(id=t_id).first()
  posts = Post.query.filter_by(thread=thread).all()
  form = PostForm()
  if form.validate_on_submit():
    post = Post(body=form.body.data,
                timestamp=datetime.utcnow(),
                thread=thread,
                author=g.user)
    db.session.add(post)
    db.session.commit()
    return redirect(url_for('thread', id=id, t_id=t_id))
  return render_template('thread.html', forum=forum, thread=thread, posts=posts, form=form, title=thread.title)

不幸的是,让这个问题自行解决的唯一可靠方法是重置实际运行应用程序的脚本run.py

#!bin/python

from app import app
app.run(debug=True,host='0.0.0.0')

2 个答案:

答案 0 :(得分:3)

您使用的是WooshAlchemy,因为它可能是您问题的一部分。 Described here

他描述了需要修改WooshAlchemy扩展的“修复”。

通常虽然它可能意味着您调用了Post模型对象,然后使用“session.add”附加它,然后尝试“session.delete”或在同一个对象上执行另一个“session.add”。

你的请求路由也有点奇怪我从未见过“thr =&lt; t_id&gt;” Flask之前的符号类型。这对你有用吗?

http://flask.pocoo.org/docs/quickstart/#variable-rules

答案 1 :(得分:0)

我认为你的编辑帖子没有正确完成。使用populate_obj函数。

@app.route('/forum=<id>/thr=<t_id>/p=<p_id>/edit', methods=['GET','POST'])
def post_edit(id, t_id, p_id):
    post = Post.query.filter_by(id=p_id).first()
    if post.author.username == g.user.username:
        form = PostForm(obj=post)
        if form.validate_on_submit():
            form.populate_obj(post)
            db.session.commit()
            return redirect(url_for('thread', id=id, t_id=t_id))
        return render_template('post_edit.html', form=form, title='Edit')
   else:
       flash('Access denied.')
       return redirect(url_for('thread', id=id, t_id=t_id))