2013-05-13 5 views
5

Sto creando un progetto del forum utilizzando Flask e gestendo tutti gli utenti, thread, post, ecc. Usando Flask-SQLAlchemy. Tuttavia, ho scoperto che quando provo a fare x (ad esempio, modifica un post), ottengo un InvalidRequestError se tento di fare qualsiasi altra cosa (ad esempio, elimina il post).Flask-SQLAlchemy InvalidRequestError: L'oggetto è già collegato alla sessione

Per la modifica di un 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(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)) 

e l'eliminazione di un post,

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

e la pubblicazione di un post

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

Purtroppo, l'unico modo sicuro per rendere questo problema risolvere è di per sé resettare lo script che esegue effettivamente l'app, run.py

#!bin/python 

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

risposta

3

stai usando WooshAlchemy perché potrebbe essere parte del problema. Described here

Descrive la "correzione" che richiede la modifica dell'estensione WooshAlchemy.

Di solito, però, potrebbe significare che hai chiamato un oggetto modello Post e poi lo hai allegato usando "session.add" e poi provato a "session.delete" o hai fatto un altro "session.add" sullo stesso oggetto.

Anche il routing della richiesta è un po 'strano per il flask Non ho mai visto il tipo di notazione "thr = <t_id>" con Flask. Ha funzionato bene per te?

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

+0

Sembra che WhooshAlchemy sia stato effettivamente il problema. Per quanto riguarda la notazione, è solo una scorciatoia per "thr = ". – Ganye

+0

Intendevo la parte "thr =". Ma immagino che potresti fare/thr = 44/p = 32/c = 21 tipi di formato url, ho appena trovato strano tutto qui. Sono contento di aver capito il problema però. – Dexter

+0

Questo è esattamente quello che è; per esempio, un thread specifico (8) in un forum (1) crea l'url "/ forum/id = 1/thr = 8". – Ganye

0

Penso che il tuo post di modifica non sia stato eseguito correttamente. Usa la funzione 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))