Это занятие
начнем с рассмотрения способа подключения внешних ресурсов к шаблону 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.
На этом завершим
это занятие. На следующем продолжим изучать функционал работы с формами.