Невозможно обновить запись с Flask, MySQL - PullRequest
0 голосов
/ 29 июня 2018

Я работаю над приложением 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')

Приложение не выдает никаких ошибок, поэтому я не уверен, что происходит, или я просто что-то пропускаю.

Ответы [ 2 ]

0 голосов
/ 30 июня 2018

Решение было таким:

Значения переменных, которые используются для обновления базы данных, должны были быть такими:

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

Поскольку в последнем методе я просто передавал те же данные в переменные, которые были загружены в форму при открытии страницы, вместо обновленных значений в текстовых полях.

0 голосов
/ 29 июня 2018

Похоже, что вы перезаписываете свою форму в посте, потому что как при получении, так и после вы выбираете запись альбома и заполняете форму с ее данными. Это должно работать, если вы структурируете это так:

def edit_album(catno):
    cur = mysql.connection.cursor()
    if request.method == 'POST':
        form = AlbumForm() # WTForms will extract data from the request's 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...

P.S. Хороший, но слишком высокоуровневый и волшебный (и непонятный в результате) пример приведен в документации WTForms : wtform имеет аргументы formdata и obj; каждый раз, когда создается экземпляр wtform (form = AlbumForm), он пытается извлечь данные из запроса для заполнения его полей. Если произойдет сбой (и это произойдет при запросе get, потому что данные формы отсутствуют), он получит данные из второго источника - аргумента obj, который имеет текущее значение db-entry. Но в post wtform успешно извлекает данные из post-request-formdata, которая затем заполняет db-запись, которая затем сохраняется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...