Статьи

Колба 101: Как добавить форму поиска

В нашей последней статье мы добавили базу данных в наше веб-приложение Flask, но не смогли добавить что-либо в нашу базу данных. У нас также не было возможности что-либо просмотреть, поэтому в итоге мы получили довольно бесполезное веб-приложение. Эта статья поможет вам научиться делать следующее:

  • Создайте форму для добавления данных в нашу базу данных.
  • Используйте форму для редактирования данных в нашей базе данных.
  • Создайте какое-то представление о том, что находится в базе данных.

Добавление форм во Flask также довольно просто, когда вы выясните, какое расширение установить. Я слышал хорошие вещи о WTForms, поэтому я буду использовать это в этом уроке. Для установки WTForms вам необходимо установить Flask-WTF . Установить Flask-WTF довольно легко; просто откройте свой терминал и активируйте виртуальную среду, которую мы создали в нашем первом уроке . Затем выполните следующую команду, используя pip:

pip install Flask-WTF

Это установит WTForms и Flask-WTF (вместе с любыми зависимостями) в виртуальную среду вашего веб-приложения.

Обслуживание файлов HTML

Первоначально, когда я начинал эту серию, все, что я обслуживал на главной странице нашего веб-приложения, было строкой. Вероятно, нам следует немного улучшить это и использовать настоящий HTML-файл. Создайте папку с именем «templates» внутри папки «musicdb». Теперь создайте файл с именем «index.html» внутри папки «templates» и поместите в него следующее содержимое:

<doctype html>
<head>
    <title>Flask Music Database</title>
</head>

<h2>Flask Music Database</h2>

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

Добавление формы поиска

При работе с базой данных вам понадобится способ поиска элементов в ней. К счастью, создать форму поиска с помощью WTForms действительно легко. Создайте скрипт Python под названием «forms.py» и сохраните его в папке «musicdb» со следующим содержимым:

# forms.py

from wtforms import Form, StringField, SelectField

class MusicSearchForm(Form):
    choices = [('Artist', 'Artist'),
               ('Album', 'Album'),
               ('Publisher', 'Publisher')]
    select = SelectField('Search for music:', choices=choices)
    search = StringField('')

Здесь мы просто импортируем нужные элементы из модуля wtforms, а затем создаем подкласс класса Form . В нашем подклассе мы создаем поле выбора (комбинированный список) и строковое поле. Это позволяет нам фильтровать наш поиск по категориям Исполнитель, Альбом или Издатель и вводить строку для поиска.

Теперь мы готовы обновить наше основное приложение.

Обновление основного приложения

Давайте переименуем скрипт нашего веб-приложения из «test.py» в «main.py» и обновим его так, чтобы он выглядел так:

# main.py

from app import app
from db_setup import init_db, db_session
from forms import MusicSearchForm
from flask import flash, render_template, request, redirect
from models import Album

init_db()


@app.route('/', methods=['GET', 'POST'])
def index():
    search = MusicSearchForm(request.form)
    if request.method == 'POST':
        return search_results(search)

    return render_template('index.html', form=search)


@app.route('/results')
def search_results(search):
    results = []
    search_string = search.data['search']

    if search.data['search'] == '':
        qry = db_session.query(Album)
        results = qry.all()

    if not results:
        flash('No results found!')
        return redirect('/')
    else:
        # display results
        return render_template('results.html', results=results)

if __name__ == '__main__':
    app.run()

Мы изменили  index() функцию, чтобы она работала как с запросами POST, так и с GET, и сказали ей загружать нашу MusicSearchForm. Вы заметите, что когда вы впервые загрузите страницу индекса вашего веб-приложения, оно выполнит GET и  index() функция отобразит наш index.html, который мы только что создали. Конечно, мы еще не добавили форму в наш index.html, поэтому поисковая форма еще не появится.

Кроме того  search_results() , мы добавили для обработки действительно простых запросов Однако эта функция не будет вызываться до тех пор, пока мы не реализуем способ отображения результатов. Итак, давайте продолжим и сделаем форму поиска видимой для наших пользователей.

Когда я изучал, как создавать формы с помощью WTForms, веб-сайт Flask-WTF  рекомендовал создать шаблон с макросом «_formhelpers.html». Создайте файл с таким именем и сохраните его в папке «templates». Затем добавьте в этот файл следующее:

{% macro render_field(field) %}
    <dt>{{ field.label }}
    <dd>{{ field(**kwargs)|safe }}
    {% if field.errors %}
        <ul class=errors>
        {% for error in field.errors %}
            <li>{{ error }}</li>
        {% endfor %}
        </ul>
    {% endif %}
    </dd>
{% endmacro %}

Этот синтаксис может показаться немного странным, поскольку он, очевидно, не просто HTML. На самом деле это  синтаксис Jinja2 , язык шаблонов, используемый Flask. По сути, везде, где вы видите волнистые скобки (то есть {}), вы видите синтаксис Jinja. Здесь мы передаем объект поля и получаем доступ к его атрибутам label и error . Не стесняйтесь искать документацию для дополнительной информации.

Теперь откройте файл «index.html» и обновите его так, чтобы он содержал следующее содержимое:

<doctype html>
<head>
    <title>Flask Music Database</title>
</head>

<h2>Flask Music Database</h2>

{% from "_formhelpers.html" import render_field %}
<form method=post>
  <dl>
    {{ render_field(form.select) }}
    <p>
    {{ render_field(form.search) }}
  </dl>
  <p><input type=submit value=Search>
</form>

Новый код в этом примере показывает, как вы можете импортировать созданный вами макрос в другой HTML-файл. Затем мы устанавливаем метод form для публикации и передаем виджет select и виджет поиска в наш макрос render_field . Мы также создаем кнопку отправки со следующим ярлыком: Поиск . Когда вы нажимаете кнопку «Поиск», она публикует данные в двух других полях формы на той странице, на которой она находится, в данном случае это наш index.html или «/».

Когда это произойдет,  index() метод в нашем сценарии main.py будет выполнен:

@app.route('/', methods=['GET', 'POST'])
def index():
    search = MusicSearchForm(request.form)
    if request.method == 'POST':
        return search_results(search)

    return render_template('index.html', form=search)

Вы заметите, что мы проверяем, какой это метод запроса, и если это метод POST, то мы вызываем  search_results() функцию. Если вы на самом деле нажмете кнопку «Поиск» на этом этапе, вы получите внутреннюю ошибку сервера, поскольку мы еще не реализовали «results.html». В любом случае, сейчас ваше веб-приложение должно выглядеть примерно так:

Название изображения

Давайте на минутку и получим функцию результатов, делающую что-то полезное

Обновление функциональности результатов

Сейчас у нас фактически нет никаких данных в нашей базе данных, поэтому, когда мы пытаемся запросить их, мы не получим никаких результатов обратно. Таким образом, нам нужно, чтобы наше веб-приложение указывало, что никаких результатов не найдено. Для этого нам нужно обновить страницу «index.html»:

<doctype html>
<head>
    <title>Flask Music Database</title>
</head>

<h2>Flask Music Database</h2>

{% with messages = get_flashed_messages() %}
  {% if messages %}
    <ul class=flashes>
    {% for message in messages %}
      <li>{{ message }}</li>
    {% endfor %}
    </ul>
  {% endif %}
{% endwith %}

{% from "_formhelpers.html" import render_field %}
<form method=post>
  <dl>
    {{ render_field(form.select) }}
    <p>
    {{ render_field(form.search) }}
  </dl>
  <p><input type=submit value=Search>
</form>

Вы заметите, что новый код — это новый блок Jinja. Здесь мы берем «мелькающие» сообщения и отображаем их. Теперь нам просто нужно запустить веб-приложение и попробовать что-то искать. Если все идет по плану, вы должны увидеть что-то вроде этого при поиске:

Название изображения

Завершение

Теперь у нас есть небольшая аккуратная форма поиска, которую мы можем использовать для поиска в нашей базе данных, хотя, честно говоря, она на самом деле не так уж много делает, поскольку наша база данных в настоящее время пуста. В нашей следующей статье мы сосредоточимся на окончательном создании способа добавления данных в базу данных, отображения результатов поиска и редактирования данных!

Скачать код

Загрузите tar-код кода из этой статьи: flask_musicdv_part_iii.tar

Другие статьи в серии

Связанные Чтения