Flask-SQLAlchemy更新正在MySQL中创建一条新记录

时间:2016-06-15 12:01:56

标签: python mysql flask flask-sqlalchemy

我正在尝试从flask-sqlalchemy更新MySQL记录,但不是更新当前记录,而是添加一个新记录。但是这里真的很奇怪,当我从Python提示符运行相同的代码时,它会正确更新而不添加新记录。

以下是代码的相关部分:

首先,提供博客的模板:

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

这是我的app文件中的代码。我从终端中的Python提示符运行完全相同的代码,它运行正常,但是当这个代码从app文件运行时,它会创建一个新记录而不是更新现有记录。

作为一个说明,我也尝试过:

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更新记录的每种方法和代码组合,我可以在此论坛和其他论坛上找到。所有相同的问题。当我从python提示符运行它们时,它们会更新数据库中的正确记录。当我从应用程序运行它们时,它们会创建一个新记录。

如果您想查看更多代码,可以在此处查看整个项目:https://github.com/tbellerose/lauraopfelphotography.com

1 个答案:

答案 0 :(得分:1)

好的,感谢Daniel和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中传递给&#39; GET&#39;方法,它没有通过&#39; POST&#39;方法(因为帖子没有来自重定向),所以我实际上在edit_entry模板中创建了一个新字段,将blog_id传回POST。