2016-06-15 1 views
2

flask-sqlalchemy에서 MySQL 레코드를 업데이트하려고하지만 현재 레코드를 업데이트하는 대신 새 레코드를 추가하고 있습니다. 그러나 여기 정말 이상한 일이 있습니다. 파이썬 프롬프트에서 동일한 코드를 실행하면 새로운 레코드를 추가하지 않고 제대로 업데이트됩니다.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) 

이가 여기

코드의 관련 부분이다 코드는 지금 내 응용 프로그램 파일에 있습니다. 터미널에서 파이썬 프롬프트와 똑같은 코드를 실행했지만 완벽하게 작동하지만이 코드가 응용 프로그램 파일에서 실행될 때 기존 코드를 업데이트하는 대신 새 레코드가 만들어집니다.

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을 교체하여 : 참고로

가, 나 또한 노력했다. 기본적으로, 나는이 포럼과 다른 것들에서 찾을 수있는 flask-sqlalchemy를 사용하여 레코드를 업데이트하기위한 모든 메소드와 코드 조합을 시도했다. 모두 같은 문제. 파이썬 프롬프트에서 실행하면 데이터베이스의 올바른 레코드를 업데이트합니다. 앱에서 실행하면 새 레코드가 만들어집니다.

당신은 코드를 더보고 싶은 경우에, 당신은 여기에 전체 프로젝트를 확인할 수 있습니다, https://github.com/tbellerose/lauraopfelphotography.com

+0

더 많은 디버깅 정보를 제공해야합니다. *'blog_id '에 대해 어떤 값이 수신되고 있습니까? 레코드를 올바르게 검색하여'post' 변수에 할당합니까? 코드가 POST 블록으로 올바르게 이동합니까? 해당 게시물 개체에 제목과 콘텐츠를 올바르게 할당합니까? 리디렉션됩니까? –

+0

'blog_id'가 문자열로 옮겨지는 것을 보았습니다 만, 여러분의 모델의'id'는 아마도 정수가 될 것입니다. 아마도 그것은 잠재적 인 고통의 포인트 일 것입니다. 또한'.first_or_404()'는 더 좋은 인자 일 수도 있고 단지'.one()'일 수도 있습니다. – Doobeh

+0

그래, 나는 블로그 템플릿에서 코드를 추가하기 위해 포스트를 업데이트했고 edit_entry에 blog_id를 피드하는 블로그 루트를 업데이트했다. 다른 질문의 경우 : 레코드를 올바르게 수신하고 있으며, 단순히 레코드의 필드를 반환하여 테스트했습니다. 나는 코드가 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) 

결국 두 가지 주요 문제가 발생했습니다. Fist는 감독이었습니다. new_entry 템플릿에서 edit_entry 템플릿을 복사 할 때 폼의 동작을 변경하는 것을 잊어 버렸기 때문에 양식이 실제로 new_entry 라우트에 게시되어 복제되었습니다. 그 문제를 발견 한 후에도 blog_id가 request.args에서 'GET'메소드로 전달되었지만 POST가 리디렉션에서 오지 않았으므로 POST 메소드로 전달되지 않았 음을 알았습니다. 사실 blog_id를 POST로 다시 전달하기 위해 edit_entry 템플릿에 새 필드를 만들었습니다.

관련 문제