Я работаю над файлом базы данных с Flask, и у меня есть страница, где я могу вставить запись в базу данных, которая работает так, как должна. Вчера я построил страницу, где вы можете редактировать значения записи. Для маршрута я скопировал код из другого, более простого приложения, которое я сделал, и переписал его для этого приложения. Когда я посещаю страницу редактирования, она заполняет текстовые поля текущими значениями для записи... но когда я меняю любой элемент и отправляю его, ничего не происходит. Он отображает страницу, указанную на маршруте после отправки, но когда я запрашиваю таблицу, ничего не изменилось.
Здесь маршрут:
@app.route('/edit_album/<string:catno>/', methods=['GET', 'POST'])
def edit_album(catno):
cur = mysql.connection.cursor()
# Get article by catno
result = cur.execute("SELECT * FROM albums WHERE catno = %s", [catno])
album = cur.fetchone()
form = AlbumForm()
form.artist.data = album['artist']
form.title.data = album['title']
form.year.data = album['year']
form.rlabel.data = album['label']
form.genre.data = album['genre']
if request.method == 'POST':
# album art
#cover =
catno = album['catno']
artist = form.artist.data
title = form.title.data
year = form.year.data
rlabel = form.rlabel.data
genre = form.genre.data
# format (lp or tape)
# Create Cursor
cur = mysql.connection.cursor()
# Execute cursor
cur.execute("UPDATE albums SET artist=%s, title=%s, year=%s, label=%s, genre=%s WHERE catno=%s", (artist, title, year, rlabel, genre, catno))
# Commit to DB
mysql.connection.commit()
# Close DB connection
cur.close()
return redirect(url_for('view_album', catno=catno))
return render_template('edit_album.html', album=album, form=form)
И вот настоящая страница редактирования:
{% extends 'layout.html' %}
{% block body %}
<div class="container">
<div class="col-md-12 text-center border mt-3">
<h1 class="text-white">{{album.artist}} :: {{album.title}}</h1>
</div>
<div class="row mt-3">
<div class="col-sm-4 col-md-4 text-center">
{% if album.albumArt == None %}
<img src="/static/album_art/not_available.png" height="300" width="300">
<a class="btn btn-primary mt-3">Upload Cover</a>
{% endif %}
</div>
<div class="col-sm-8 col-md-8">
<table class="table table-light table-striped">
<tr>
<td>Artist: {{album.artist}}</td>
</tr>
<tr>
<td>Album: {{album.title}}</td>
</tr>
<tr>
<td>Catalog No: {{album.catno}}</td>
</tr>
<tr>
<td>Record Label: {{album.label}}</td>
</tr>
<tr>
<td>Year Released: {{album.year}}</td>
</tr>
<tr>
<td>Genre: {{album.genre}}</td>
</tr>
</table>
</div>
</div>
<div class="card text-center mt-3">
<div class="card-header text-center bg-primary">
<p>EDIT ALBUM</p>
</div>
<form method="POST" action="{{ url_for('edit_album', catno=album.catno) }}" class="card-footer text-center">
<div class="row">
{{ form.csrf_token}}
<div class="col-sm-4">
{{ form.artist.label }}<br>
{{ form.artist }}<br>
</div>
<div class="col-sm-4">
{{ form.title.label }}<br>
{{ form.title }}<br>
</div>
<div class="col-sm-4">
{{ form.year.label }}<br>
{{ form.year }}<br>
</div>
</div>
<div class="row">
<div class="col-sm-4">
{{ form.rlabel.label }}<br>
{{ form.rlabel }}<br>
</div>
<div class="col-sm-4">
{{ form.genre.label }}<br>
{{ form.genre }}
</div>
</div>
<p><input class="btn btn-primary mt-3" type="submit" value="Submit">
</form>
</div>
</div>
{% endblock %}
Единственное, что я действительно получил от поиска прошлой ночью, это то, что у меня может быть два подключения к БД открытыми, но я не с тех пор, как у меня есть только одно соединение в начале скрипта. Это не было бы проблемой со слишком большим количеством курсоров, не так ли?
В противном случае это первое приложение, в котором я использовал модуль Flask-WTF для форм, так что это может быть что-то неправильно? Я делаю с этим? Вот этот класс, если есть вопросы:
# Form for adding record to database
class AlbumForm(FlaskForm):
# Album Art - figure out image uploads
cover = FileField('Upload Cover Art')
catno = StringField('Catalog Number')
artist = StringField('Artist')
title = StringField("Album Title")
year = StringField('Year Released')
rlabel = StringField('Record Label')
genre = StringField('Genre')
Приложение не бросает никаких ошибок, поэтому я не уверен, что происходит, или если я просто что-то пропускаю.
Решением было следующее:
Значение переменных, которые используются для обновления базы данных, должно было быть таким:
catno = album['catno']
artist = request.form['artist']
title = request.form['title']
year = request.form['year']
rlabel = request.form['rlabel']
genre = request.form['genre']
И не:
catno = album['catno']
artist = form.artist.data
title = form.title.data
year = form.year.data
rlabel = form.rlabel.data
genre = form.genre.data
Поскольку в последнем методе я просто передавал одни и те же данные в переменные, которые были загружены в форму при открытии страницы, вместо обновленных значений в текстовых полях.
Похоже, вы переписываете свою форму на почту, потому что на обоих вы получаете и публикуете запись альбома и подаете форму с данными. Он должен работать, если вы структурируете его следующим образом:
def edit_album(catno):
cur = mysql.connection.cursor()
if request.method == 'POST':
form = AlbumForm() # WTForms will extract data from the request body by itself
# other code from a if request.method == 'POST' block
elif request.method == 'GET':
cur.execute("...")
album = cur.fetchone()
form = AlbumForm()
form.artist.data = album['artist']
form.title.data = album['title']
form.year.data = album['year']
form.rlabel.data = album['label']
form.genre.data = album['genre']
return render_template...
PS Хороший, но слишком высокоуровневый и волшебный (и трудно понять как результат) пример приведен в документах WTForms: wtform имеет аргументы formdata
и obj
; каждый раз, когда создается экземпляр wtform (form = AlbumForm
), он пытается извлечь данные из запроса, чтобы заполнить его поля. Если он терпит неудачу (и он будет получать запрос, потому что нет данных формы), он получит данные из второго источника - аргумент obj
, который имеет текущее значение db-entry. Но на post wtform успешно извлекает данные из данных post-request-formdata, которые затем заполняют db-запись, которая затем сохраняется.