2013-05-13 10 views
5

Tworzę projekt forum za pomocą Flask i zarządzam wszystkimi użytkownikami, wątkami, wpisami itp. Za pomocą Flask-SQLAlchemy. Jednak odkryłem, że gdy próbuję zrobić x (na przykład edytować post), otrzymuję InvalidRequestError, jeśli próbuję zrobić cokolwiek innego (np. Usunąć wpis).Flask-SQLAlchemy InvalidRequestError: Obiekt jest już dołączony do sesji

do edycji posta,

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

i usuwanie posta

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

i zamieszczając wpis

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

Niestety, jedyną murowany sposób, aby ten problem determinację sam zresetować skrypt, który faktycznie uruchamia aplikację, run.py

#!bin/python 

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

Odpowiedz

3

Używasz WooshAlchemy, ponieważ może to być częścią twojego problemu. Described here

Opisuje "poprawkę", która wymaga modyfikacji rozszerzenia WooshAlchemy.

Zwykle może to oznaczać, że wywołasz obiekt modelu Post, a następnie dołączasz go za pomocą "session.add", a następnie próbowałeś "session.delete" lub zrobiłeś inny "session.add" na tym samym obiekcie.

Także twoja prośba o routing jest trochę dziwna w przypadku flakonu Nigdy wcześniej nie widziałem "thr = <t_id>" typu notacji z Flaską wcześniej. Czy to działa dobrze dla ciebie?

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

+0

Wygląda WhooshAlchemy rzeczywiście był problem. Jeśli chodzi o notację, jest to skrót "thr = ". – Ganye

+0

Miałem na myśli część "thr =". Ale domyślam się, że możesz zrobić/thr = 44/p = 32/c = 21 rodzaj formatu URL, po prostu uznałem za dziwne to wszystko. Cieszę się, że udało nam się rozwiązać problem. – Dexter

+0

Dokładnie to jest; więc na przykład określony wątek (8) na forum (1) tworzy adres URL "/ forum/id = 1/thr = 8". – Ganye

0

Wydaje mi się, że Twój post edycji nie jest poprawnie wykonany. Użyj funkcji 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)) 
Powiązane problemy