Обновление Flask-SQLAlchemy создает новую запись в MySQL
Я пытаюсь обновить запись MySQL из flask-sqlalchemy, но вместо обновления текущей записи она добавляет новую. Но вот действительно странная вещь: когда я запускаю тот же код из приглашения 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)
Это код, который находится сейчас в моем файле приложения. Я запустил точно такой же код из командной строки Python в терминале, и он отлично работает, но когда этот код запускается из файла приложения, он создает новую запись вместо обновления существующей.
Как примечание, я также попробовал:
models.Blog.query.filter_by(id=blog_id).update({
'title': form.title.data,
'content': form.content.data
})
db.session.commit()
и путем замены models.Blog на db.session.query(models.Blog). В основном, я попробовал каждый метод и комбинацию кода для обновления записей с использованием flask-sqlalchemy, которые я мог найти на этом форуме и других. Все та же проблема. Когда я запускаю их из приглашения python, они обновляют правильную запись в базе данных. Когда я запускаю их из приложения, они создают новую запись.
Если вы хотите увидеть больше кода, вы можете проверить весь проект здесь: https://github.com/tbellerose/lauraopfelphotography.com
1 ответ
Хорошо, спасибо Дэниелу и Дубе за то, что они указали мне правильные направления. В основном это было связано с тем, что я не запрашивал blog_id должным образом в методе POST edit_entry. Вот новый (и рабочий) код.
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)
Там оказались две основные проблемы. Кулак был недосмотром: когда я скопировал шаблон edit_entry из шаблона new_entry, я забыл изменить действие формы, поэтому форма фактически отправляла по маршруту new_entry, таким образом, дублирование. После того, как я обнаружил эту проблему, я также понял, что хотя blog_id передавался в request.args методу 'GET', он не передавался в методе 'POST' (так как сообщение не приходило из перенаправления), поэтому Я на самом деле создал новое поле в шаблоне edit_entry для передачи blog_id обратно в POST.