Подключение внешних ресурсов и работа с формами

Это занятие начнем с рассмотрения способа подключения внешних ресурсов к шаблону HTML-документа. Наверное, многие из вас знают, что полноценные страницы сайта представляются не только файлом HTML с набором тегов, но и, например, каскадными таблицами стилей (CSS), JavaScript-программами, которые исполняются в браузере клиента и другими дополнительными внешними ресурсами.

И здесь возникает вопрос: где расположить эти вспомогательные файлы, которые, как правило, являются общими для всех страниц сайта, и как прописать к ним путь в шаблоне HTML-страницы. Для этого, как раз хорошо подходит функция

url_for

о которой мы говорили на предыдущем занятии. Ее также можно вызывать непосредственно в шаблоне и она будет связана с текущим контекстом запроса, по которому берется шаблон. То есть, функция url_for корректно отработает и корректно возвратит запрашиваемый URL-адрес. Но что следует прописать первым аргументом у этой функции. Как мы говорили, там должно фигурировать имя функции-обработчика. Но здесь же нам нужен не обработчик а путь к внешнему файлу. Для этого во Flask для url_for зарезервировано специальный параметр

'static'

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

filename='css/styles.css'

Давайте подключим оформление к страницам сайта в шаблоне base.html, используя эту функцию:

<link type="text/css" href="{{ url_for('static', filename='css/styles.css')}}" rel="stylesheet" />

В данном случае функция url_for возвратит путь:

static/css/styles.css

и в шаблон будет подключен этот файл оформления страницы. Содержимое этого файла следующее (см. видео). Я не буду здесь подробно объяснять как работают эти стили, если вы не знакомы с CSS, то посмотрите это занятие.

Обновим страницу, увидим следующий результат:

Чтобы таблицы стилей были применены к соответствующим элементам HTML-документа, добавим следующие строчки (в base.html):

<ul class="mainmenu"></ul>
<div class="clear"></div>
<div class="content"></div>

Теперь, при обновлении увидим такую страницу:

Далее, добавим ссылки нашим пунктам меню:

<li><a href="{{m.url}}">{{m.name}}</a></li>

А само меню в программе представим в виде списка словарей:

menu = [{"name": "Установка", "url": "install-flask"},
        {"name": "Первое приложение", "url": "first-app"},
        {"name": "Обратная связь", "url": "contact"}]

Теперь при обновлении страницы мы увидим полноценное меню.

Аналогичным образом можно подключать и другие внешние файлы.

Работа с формой (form)

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

Они описываются на странице с помощью тега form, в параметре action указывается URL, который должен принимать данные от формы, а параметр method определяет способ передачи данных. В основном, используются два вида передачи:

  • GET – в виде строки запроса: "/handler?name=Alex&old=18&profit=1000";
  • POST – в виде бинарных данных (используется для передачи больших объемов данных: изображений, звуков, документов и т.п., а также закрытых сведений: паролей, логинов и т.п.).

Добавим форму в шаблон contact.html:

{% extends 'base.html' %}
 
{% block content %}
{{ super() }}
<form action="/contact" method="post" class="form-contact">
<p><label>Имя: </label> <input type="text" name="username" value="" requied />
<p><label>Email: </label> <input type="text" name="email" value="" requied />
<p><label>Сообщение:</label>
<p><textarea name="message" rows=7 cols=40></textarea>
<p><input type="submit" value="Отправить" />
</form>
{% endblock %}

Мы здесь указали способ отправки данных в виде POST-запроса и обработчик «/contact», которому будут переданы данные из формы.

Далее, пропишем следующее оформление формы (в файле styles.css):

.form-contact label {
         display: inline-block; 
         min-width: 80px;
}
 
.form-contact p {margin: 10px 0 10px 0;}
.form-contact input[type=submit], textarea {
         font-size: 16px;
}

Запустим программу, откроем в браузере страницу

http://127.0.0.1:5000/contact

и увидим следующий результат:

Если сейчас ввести в форму какие-либо данные и нажать на кнопку отправить, то сервер возвратит ошибку:

405 – запрет на прием данных (Method Not Allowed)

Дело в том, что в обработчике мы должны явно указать: может ли он принимать данные методом POST. Для этого нужно прописать параметр methods со значением POST как элемент списка:

@app.route("/contact", methods=["POST"])

Или так, если хотим обрабатывать и POST и GET запросы:

@app.route("/contact", methods=["POST", "GET"])

Далее в обработчике проверим: пришел ли именно POST-запрос, а не какой-либо другой и выведем данные в консоль:

    if request.method == 'POST':
        print(request.form)

А вначале импортируем этот объект:

from flask import Flask, render_template, request

Мы здесь используем объект request, который связан с данными текущего запроса и существует в пределах контекста запроса, как мы это отмечали на предыдущих занятиях. Далее, все данные формы доступны по свойству form, которое представляет своеобразный словарь, то есть, для доступа к конкретному полю можно использовать следующую запись:

print(request.form['username'])

Мы пока не будем нигде сохранять принятые данные, т.к. для этого следует использовать БД, о которой еще ничего не говорили. Главное, на этом этапе понимать, как происходит прием данных от формы и их представление в объекте request.

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

Видео по теме