Flask-SQLAlchemy更新正在MySQL中创建新记录 [英] A Flask-SQLAlchemy update is creating a new record in MySQL

查看:256
本文介绍了Flask-SQLAlchemy更新正在MySQL中创建新记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从flask-sqlalchemy更新一条MySQL记录,但是它没有添加当前记录,而是添加了一条新记录.但是,这确实很奇怪,当我在Python提示符下运行相同的代码时,它可以正确更新而无需添加新记录.

I am trying to update a MySQL record from flask-sqlalchemy, but instead of updating the current record, it is adding a new one. But here's the really weird thing, when I run the same code from the Python prompt it updates properly without adding a new record.

这是代码的相关部分:

首先,提供博客的模板:

First, the template that feeds the blog:

{% 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提示符中运行了完全相同的代码,并且运行完美,但是当此代码从应用程序文件运行时,它会创建一条新记录,而不是更新现有记录.

This is the code as it is right now in my app file. I've run the exact same code from the Python prompt in the terminal, and it works perfectly, but when this code runs from the app file, it creates a new record instead of updating the existing one.

请注意,我也尝试过:

models.Blog.query.filter_by(id=blog_id).update({
    'title': form.title.data,
    'content': form.content.data
})
db.session.commit()

,然后将model.Blog替换为db.session.query(models.Blog).基本上,我已经尝试过使用flask-sqlalchemy更新记录的所有方法和代码组合,这些我可以在该论坛和其他论坛上找到.都是一样的问题.当我从python提示符下运行它们时,它们将更新数据库中的正确记录.当我从应用程序运行它们时,它们会创建一条新记录.

and by replacing models.Blog with db.session.query(models.Blog). Basically, i've tried every method and combination of code for updating records using flask-sqlalchemy that I could find on this forums and others. All the same issue. When I run them from the python prompt, they update the correct record in the database. When I run them from the app, they create a new record.

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

If you want to see more of the code, you can check the entire project here: https://github.com/tbellerose/lauraopfelphotography.com

推荐答案

好的,非常感谢Daniel和Doobeh为我指明了正确的方向.基本上,这归结为我没有在edit_entry的POST方法中正确请求blog_id.这是新的(有效的)代码.

Okay, so thanks to Daniel and Doobeh for pointing me in the right directions. Basically it came down to me not requesting the blog_id properly in the POST method of edit_entry. Here is the new (and working) code.

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)

最终有两个主要问题.拳头是一个疏忽:当我从new_entry模板复制edit_entry模板时,我忘记更改表单的操作,因此该表单实际上是投递到new_entry路由,因此是重复的.发现问题后,我还意识到,虽然在request.args中将blog_id传递给了'GET'方法,但并未在'POST'方法中传递它(因为发布不是来自重定向的),所以我实际上在edit_entry模板中创建了一个新字段,以将blog_id传递回POST.

There ended up being two major issues. Fist was an oversight: when I copied the edit_entry template from the new_entry template, I forgot to change the action of the form, so the form was actually posting to the new_entry route, thus the duplication. After I found that problem, I also realized that while blog_id was passed in request.args to the 'GET' method, it wasn't being passed in the 'POST' method (since post wasn't coming from the redirect), so I actually created a new field in the edit_entry template to pass the blog_id back to POST.

这篇关于Flask-SQLAlchemy更新正在MySQL中创建新记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆