2013-05-13 1 views
5

Я создаю проект форума с использованием Flask и управляю всеми пользователями, потоками, сообщениями и т. Д. С помощью Flask-SQLAlchemy. Однако я обнаружил, что когда я пытаюсь выполнить x (например, отредактировать сообщение), я получаю InvalidRequestError, если я попытаюсь сделать что-нибудь еще (например, удалить сообщение).Flask-SQLAlchemy 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') 

ответ

3

Вы используете WooshAlchemy, потому что это может быть частью вашей проблемы. Described here

Он описывает «исправление», требующее модификации расширения WooshAlchemy.

Обычно, хотя это может означать, что вы вызвали объект модели Post, а затем привязали его с помощью «session.add», а затем попытались «session.delete» или сделали еще один «session.add» на том же объекте.

Также ваша маршрутизация запроса немного странная для фляжки. Я никогда не видел «обозначение типа« thr = <t_id> »с флягой раньше. Это хорошо работает для вас?

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

+0

Похоже WhooshAlchemy действительно проблема. Что касается обозначений, это всего лишь сокращение для «thr = ». – Ganye

+0

Я имел в виду часть «thr =». Но я думаю, вы могли бы сделать/thr = 44/p = 32/c = 21 вид формата url, мне просто показалось странным, что все. Я рад, что мы разобрались с проблемой. – Dexter

+0

Это именно то, что есть; поэтому, например, конкретный поток (8) в форуме (1) создает URL-адрес «/ forum/id = 1/thr = 8». – Ganye

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))