2016-06-15 12 views
2

フラスコのsqlalchemyからMySQLレコードを更新しようとしていますが、現在のレコードを更新する代わりに新しいレコードを追加しています。しかし、本当に奇妙なことですが、Pythonプロンプトから同じコードを実行すると、新しいレコードを追加せずに正しく更新されます。Flask-SQLAlchemyアップデートがMySQLで新しいレコードを作成しています

まず、ブログのフィードテンプレート:今

{% for post in posts %} 
    <article class="blog"> 
    <header> 
     <h2>{{ post.title|safe }}</h2> 
    </header> 
    <main> 
     {{ post.content|safe }} 
    </main> 
    <footer> 
     <p>{{ post.posted.strftime('%d %B %Y %I:%M')|safe }}<p> 
     {% if session.logged_in %} 
     <form action="{{ url_for('blog') }}" method="post"> 
      <div style="display:none;"> 
      <input type="hidden" name="blog_id" value="{{ post.id|safe }}"> 
      </div> 

      <div class="form-group submit"> 
      <input type="submit" name="submit" class="btn" value="Edit Post"> 
      <input type="submit" name="submit" class="btn" value="Delete Post"> 
      </div> 
     </form> 
     {% endif %} 
    </footer> 
    </article> 
{% endfor %} 

を、ビューのコード:

@app.route('/blog', methods = ['GET', 'POST']) 
def blog(): 
    # Get all records from database blog table: 
    posts = models.Blog.query.order_by(models.Blog.posted.desc()).all() 
    context = { 
     'copyright': COPYRIGHT, 
     'posts': posts 
    } 
    if request.method == 'POST': 
     blog_id = request.form.get('blog_id') 
     if request.form.get('submit') == 'Edit Post': 
      return redirect(url_for('edit_entry', blog_id = blog_id)) 
     elif request.form.get('submit') == 'Delete Post': 
      pass 
    elif request.method == 'GET': 
     return render_template('blog.html', **context) 

@app.route('/edit_entry', methods = ['GET', 'POST']) 
def edit_entry(): 
    form = BlogEntry() # A WTForms object. 
    # blog_id is passed from a redirect. Tested and ensured it is passing proper value. 
    blog_id = request.args['blog_id'] 
    post = models.Blog.query.filter_by(id = blog_id).one() 
    if request.method == 'POST': 
     post.title = form.title.data 
     post.content = form.content.data 
     db.session.commit() 
     return redirect(url_for('blog')) 
    elif request.method == 'GET': 
     context = { 
      'copyright': COPYRIGHT, 
      'form': form, 
     } 
     form.title.data = post.title 
     form.content.data = post.content 
     return render_template('edit_entry.html', **context) 

がこれはここ

はコードの関連部分でありますコードは今の私のアプリファイルにあります。私は、ターミナルのPythonプロンプトから完全に同じコードを実行しましたが、完全に動作しますが、このコードをアプリケーションファイルから実行すると、既存のコードを更新する代わりに新しいレコードが作成されます。注意点として

、私も試みた:

models.Blog.query.filter_by(id=blog_id).update({ 
    'title': form.title.data, 
    'content': form.content.data 
}) 
db.session.commit() 
およびdb.session.query(models.Blog)とmodels.Blogを置き換えることによって。基本的には、私はこのフォーラムなどで見つけることができるフラスコ - sqlalchemyを使用してレコードを更新するためのすべてのメソッドとコードの組み合わせを試しました。すべて同じ問題。私はpythonプロンプトからそれらを実行すると、データベースの正しいレコードを更新します。私はアプリからそれらを実行すると、彼らは新しいレコードを作成します。

あなたは、コードの詳細を参照したい場合は、ここで、プロジェクト全体をチェックすることができます:https://github.com/tbellerose/lauraopfelphotography.com

+0

さらにデバッグ情報を提供する必要があります。 * 'blog_id'には何の価値がありますか?レコードを正しく取り出して 'post'変数に代入しますか?コードがPOSTブロックに正しく入りますか?その投稿オブジェクトにタイトルとコンテンツを正しく割り当てていますか?それはリダイレクトされますか? –

+0

'blog_id'は文字列として移動していますが、モデルの' id'は整数である可能性があります。おそらくそれは潜在的な苦境点です。また '.first_or_404()'はより良い引数かもしれず、 '.one()'だけかもしれません。 – Doobeh

+0

さて、ブログテンプレートからコードを追加するように投稿を更新しました。blog_idにedit_entryをフィードするブログルートを追加しました。その他の質問:レコードを正しく受け取っています。レコードからフィールドを返すだけでテストしました。コードがPOSTに正しく入っているかどうかを調べようとしていますが、POST変数を参照するためにrender_templateに変更したにもかかわらず、ブログにリダイレクトされている問題が発生していますedit_entryによって送信されます。 – Tyler

答えて

1

大丈夫なので、右方向に私を指しためのダニエルとDoobehのおかげで。基本的には、edit_entryのPOSTメソッドでblog_idを正しく要求していないということが私に伝わりました。ここに新しい(そして動作する)コードがあります。

def edit_entry(): 
    form = BlogEntry() 
    if request.method == 'POST': 
     blog_id = request.form.get('blog_id') 
     update = db.session.query(models.Blog).filter_by(id = blog_id).update({ 
      'title': request.form.get('title'), 
      'content': request.form.get('content') 
     }) 
     db.session.commit() 
     return redirect(url_for('blog')) 
    elif request.method == 'GET': 
     blog_id = int(request.args['blog_id']) 
     post = models.Blog.query.filter_by(id = blog_id).first_or_404() 
     context = { 
      'copyright': COPYRIGHT, 
      'form': form, 
      'blog_id': blog_id 
     } 
     form.title.data = post.title 
     form.content.data = post.content 
     return render_template('edit_entry.html', **context) 

2つの大きな問題がありました。私はedit_entryテンプレートをnew_entryテンプレートからコピーしたときに、フォームのアクションを変更するのを忘れていたので、フォームはnew_entryルートに実際に投稿していたので、重複していました。その問題を見つけた後、blog_idがrequest.argsで 'GET'メソッドに渡されたのに対し、POSTメソッドで渡されていないことがわかりました(投稿はリダイレクトから来ていないので)私は実際にblog_idをPOSTに戻すためにedit_entryテンプレートに新しいフィールドを作成しました。

関連する問題