Шаблоны¶
Вы написали представления аутентификации для своего приложения, но если вы запустите сервер и попытаетесь перейти по любому из URL, вы увидите ошибку TemplateNotFound
. Это происходит потому, что представления вызывают render_template()
, но вы еще не написали шаблоны. Файлы шаблонов будут храниться в каталоге templates
внутри пакета flaskr
.
Шаблоны - это файлы, содержащие статические данные, а также заполнители для динамических данных. Шаблон отображается с определенными данными для создания конечного документа. Flask использует библиотеку шаблонов Jinja для рендеринга шаблонов.
В своем приложении вы будете использовать шаблоны для рендеринга HTML, которые будут отображаться в браузере пользователя. Во Flask Jinja настроена на автоскейп любых данных, которые отображаются в HTML-шаблонах. Это означает, что ввод данных пользователем безопасен; все введенные им символы, которые могут испортить HTML, такие как <
и >
, будут escaped с safe значениями, которые выглядят одинаково в браузере, но не вызывают нежелательных эффектов.
Jinja выглядит и ведет себя в основном как Python. Чтобы отличить синтаксис Jinja от статических данных в шаблоне, используются специальные разделители. Все, что находится между {{
и }}
, является выражением, которое будет выведено в конечный документ. {%
и %}
обозначает оператор потока управления, как if
и for
. В отличие от Python, блоки обозначаются тегами начала и конца, а не отступами, поскольку статический текст внутри блока может изменить отступ.
Базовая компоновка¶
Каждая страница в приложении будет иметь одинаковый базовый макет вокруг разного тела. Вместо того чтобы писать всю структуру HTML в каждом шаблоне, каждый шаблон будет расширять базовый шаблон и переопределять определенные разделы.
<!doctype html>
<title>{% block title %}{% endblock %} - Flaskr</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<nav>
<h1>Flaskr</h1>
<ul>
{% if g.user %}
<li><span>{{ g.user['username'] }}</span>
<li><a href="{{ url_for('auth.logout') }}">Log Out</a>
{% else %}
<li><a href="{{ url_for('auth.register') }}">Register</a>
<li><a href="{{ url_for('auth.login') }}">Log In</a>
{% endif %}
</ul>
</nav>
<section class="content">
<header>
{% block header %}{% endblock %}
</header>
{% for message in get_flashed_messages() %}
<div class="flash">{{ message }}</div>
{% endfor %}
{% block content %}{% endblock %}
</section>
g
автоматически доступен в шаблонах. В зависимости от того, установлено ли значение g.user
(из load_logged_in_user
), отображается либо имя пользователя и ссылка для выхода из системы, либо ссылки для регистрации и входа в систему. url_for()
также автоматически доступен и используется для генерации URL-адресов представлений вместо того, чтобы писать их вручную.
После заголовка страницы и перед содержимым шаблон зацикливает каждое сообщение, возвращаемое get_flashed_messages()
. Вы использовали flash()
в представлениях для отображения сообщений об ошибках, а это код, который будет их отображать.
Здесь определены три блока, которые будут переопределены в других шаблонах:
{% block title %}
изменит заголовок, отображаемый в заголовке вкладки и окна браузера.{% block header %}
аналогиченtitle
, но изменяет заголовок, отображаемый на странице.{% block content %}
- это место, куда помещается содержимое каждой страницы, например, форма входа в систему или запись в блоге.
Базовый шаблон находится непосредственно в каталоге templates
. Для того чтобы остальные были организованы, шаблоны для чертежа будут помещены в каталог с тем же именем, что и чертеж.
Зарегистрироваться¶
{% extends 'base.html' %}
{% block header %}
<h1>{% block title %}Register{% endblock %}</h1>
{% endblock %}
{% block content %}
<form method="post">
<label for="username">Username</label>
<input name="username" id="username" required>
<label for="password">Password</label>
<input type="password" name="password" id="password" required>
<input type="submit" value="Register">
</form>
{% endblock %}
{% extends 'base.html' %}
сообщает Jinja, что этот шаблон должен заменить блоки из базового шаблона. Все отображаемое содержимое должно находиться внутри тегов {% block %}
, которые заменяют блоки из базового шаблона.
Полезным шаблоном здесь является размещение {% block title %}
внутри {% block header %}
. Это установит блок заголовка, а затем выведет его значение в блок заголовка, так что и окно, и страница имеют один и тот же заголовок без записи его дважды.
Теги input
здесь используют атрибут required
. Это указывает браузеру не отправлять форму, пока эти поля не будут заполнены. Если пользователь использует более старый браузер, который не поддерживает этот атрибут, или если он использует что-то помимо браузера для выполнения запросов, вы все равно хотите проверить данные в представлении Flask. Важно всегда полностью проверять данные на сервере, даже если клиент также выполняет некоторую проверку.
Войти¶
Этот шаблон идентичен шаблону регистрации, за исключением заголовка и кнопки отправки.
{% extends 'base.html' %}
{% block header %}
<h1>{% block title %}Log In{% endblock %}</h1>
{% endblock %}
{% block content %}
<form method="post">
<label for="username">Username</label>
<input name="username" id="username" required>
<label for="password">Password</label>
<input type="password" name="password" id="password" required>
<input type="submit" value="Log In">
</form>
{% endblock %}
Регистрация пользователя¶
Теперь, когда шаблоны аутентификации написаны, вы можете зарегистрировать пользователя. Убедитесь, что сервер все еще запущен (flask run
, если это не так), затем перейдите на http://127.0.0.1:5000/auth/register.
Попробуйте нажать кнопку «Регистрация» без заполнения формы и убедитесь, что браузер выдает сообщение об ошибке. Попробуйте удалить атрибуты required
из шаблона register.html
и снова нажмите кнопку «Регистрация». Вместо того чтобы браузер показал ошибку, страница перезагрузится и будет показана ошибка из flash()
в представлении.
Заполните имя пользователя и пароль, и вы будете перенаправлены на страницу входа в систему. Попробуйте ввести неправильное имя пользователя или правильное имя пользователя и неправильный пароль. Если вы войдете в систему, то получите ошибку, потому что пока нет представления index
, на которое можно было бы перенаправить.
Продолжить Статические файлы.