Функции flash и get_flashed_messages фреймворка Flask

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

Начнем с заголовка. Если страница запрошена методом POST и содержимое поля h1 равно пустой строке, то при загрузке страницы, помимо возврата данных в форму, необходимо сообщить пользователю, что он сделал не так. И здесь на помощь приходит функция flash модуля flask (предварительно ее надо импортировать).

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        if request.form['h1'] == '':
            flash('Пропущен заголовок!')
    return render_template('create.html', sections=sections)

При этом будет возникать ошибка, так как для вызова flash() нужен секретный ключ. Поэтому после строки создания объекта Flask следует его добавить.

app = Flask(__name__)
app.config['SECRET_KEY'] = 'enter your key'

В шаблоне перед формой добавим контейнер для вывода сообщений:

{% for message in get_flashed_messages() %}
    <p style="color:red;text-align:center">{{ message }}</p>
{% endfor %}

Функция get_flashed_messages() возвращает все flash-сообщения, которые были сгенерированы и накоплены при выполнении скрипта.

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

Проверка будет считаться пройденной, если такой записи не найдется.

def test_path(path):
    c = sqlite3.connect(db_name)
    p = c.execute('SELECT * FROM articles WHERE path=?', (path, )).fetchone()
    c.close()
    return p is None


@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        if request.form['h1'] == '':
            flash('Пропущен заголовок!')
        elif request.form['path'] == '':
            flash('Строка адреса пуста!')
        elif not test_path(request.form['path']):
            flash('Страница с таким адресом уже есть!')
        else:
            # Запись статьи в базу данных (не реализовано)
            # Перенаправление на только что созданную страницу (не реализовано)
            flash('Страница создана!')
    return render_template('create.html', sections=sections)

Перед этим также следует проверять на отсутствие пустоты в строке адреса. В нашем случае записи в БД с адресом главной страницы не будет.

После того, как все проверки успешно пройдены, статья должна записываться в базу данных. Кроме того, мы будем перенаправлять пользователя на эту страницу. При этом вспомним, что в нашем проекте есть две разных python-программы. Первая ‒ "пользовательская" для отображения статей. Вторая, над которой сейчас работаем, ‒ для их создания и редактирования.

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

Все это немного отличается от того, как принято в популярных системах управления контентом (CMS). В них при нажатии на кнопку "Сохранить", вас перенаправляет по адресу статьи, где она предстает в готовом опубликованном виде. Если надо ее править, то тут же есть кнопка "Правка", при нажатии на которую открывается форма для редактирования статьи. Адреса страницы с формой для правки и самой страницы отличаются.

Мы могли бы разрабатывать flask-приложение для администратора подобным образом. Однако будет проще запускать на одном локальном сервере два приложения. В одном смотреть, как выглядят страницы в готовом виде, в другом ‒ выполнять правку сайта. Когда сайт будет работать на удаленном веб-сервере, то второе приложение там не нужно. После правки базы данных на локальном сервере, нужно будет копировать ее на удаленный, где она перезапишет старую версию. Или в скрипте admin.py сразу настроить подключение к удаленной базе данных (не вариант в случае использования SQLite).

Пока вернемся к функции flash и обратим внимание на то, что сообщения в случае неверного заполнения формы выводятся красным цветом. Хорошо бы при положительном исходе выводить фразу "Страница создана!" каким-нибудь другим цветом, например, зеленым. Это легко реализовать, так как flash предусматривает возможность передачи второго аргумента, который играет роль категории сообщения (вы их придумываете сами).

if request.form['h1'] == '':
    flash('Пропущен заголовок!', 'error')
elif request.form['path'] == '':
    flash('Строка адреса пуста!', 'error')
elif not test_path(request.form['path']):
    flash('Страница с таким адресом уже есть!', 'error')
else:
    # Запись статьи в базу данных (не реализовано)
    # Перенаправление на только что созданную страницу (не реализовано)
    flash('Страница создана!', 'success')

В шаблоне категория может использоваться как имя класса:

{% block styles_scripts %}
<style>
    .error { color: red; text-align: center; }
    .success { color: green; text-align: center; }
</style>
{% endblock %}

... 

{% for category, message in get_flashed_messages(with_categories=true) %}
    <p class="{{ category }}">{{ message }}</p>
{% endfor %}

В данном случае необходимо при вызове функции get_flashed_messages установить параметр with_categories в значение true.

Flask для начинающих




Все разделы сайта