Введение в колбу: добавление контактной страницы

24 января 2018

В предыдущей статье этой мини-серии мы использовали Flask для создания простого веб-сайта, содержащего страницы «Главная» и «О», используя обобщенный рабочий процесс, который мы можем применить к другим веб-приложениям на базе Flask. В этом уроке я продемонстрирую, как добавить страницу «Контакт», которая позволяет пользователям отправлять вам сообщения.

Код, используемый в этой статье, можно найти в GitHub. Подписи, такие как контрольная точка: 05_contact_form, означают, что вы можете переключиться на ветвь с именем «05_contact_form» и просмотреть код в этой точке статьи.


Расширения фляг

Полный список расширений вы можете найти в реестре расширений флагов.

Фляга не имеет много функций с полки, что позволяет легко подобрать и изучить. Для добавления и обновления контента нет объектно-реляционного преобразователя для взаимодействия с базами данных или админ-интерфейсов. Он предлагает только небольшой набор функций, два из которых мы уже использовали - url_for () и render_template ().

Вместо доставки с дополнительной функциональностью модель расширения Flask позволяет добавлять функциональные возможности по мере необходимости. Расширение фляшки - это пакет, который добавляет определенные функции вашему приложению. Например, Flask-SQLAlchemy добавляет поддержку базы данных в ваше приложение, тогда как Flask-Login добавляет поддержку входа в систему. Полный список расширений вы можете найти в реестре расширений флагов.

Чтобы создать страницу контакта, мы будем использовать Flask-WTF для обработки и проверки данных формы и Flask-Mail для отправки вам данных формы.


Flask-WTF

Flask-WTF - это расширение, которое обрабатывает и проверяет данные формы. Что это значит? Посмотрите на следующий рисунок:

    Пользователь выдает запрос GET для веб-страницы, содержащей форму. Пользователь заполняет форму. Пользователь нажимает кнопку «Отправить», отправляя ее на сервер через запрос POST. Сервер проверяет информацию. Если одно или несколько полей не проверяются, веб-страница, содержащая форму, снова загружается с полезным сообщением об ошибке, предлагая повторить попытку пользователя. Если все поля проверяются, информация о форме используется на следующем этапе в конвейере.

На странице контакта будут указаны поля для имени пользователя, электронной почты, темы и сообщения. В Flask мы отправим форму в функцию внутри routes.py. Эта функция называется обработчиком формы. Мы проверим несколько проверок проверки, и если какой-либо вход не пройдет, мы обновим страницу, чтобы отобразить сообщение, описывающее ошибку. Как только все проверки пройдут проверку, мы будем использовать данные формы для следующего шага: отправив вам сообщение владельцу веб-сайта.

Расширения флэков - это простые, мощные инструменты, расширяющие функциональность вашего приложения на фляже.

Вот как работает обработка и проверка формы. Теперь, где мы фактически определяем форму? Мы могли бы написать HTML с помощью элемента

и установить его атрибут действия в скрипт Python. Сценарий Python будет отображать форму для захвата каждого поля формы и проверки данных поля формы. Однако, если мы используем эту стратегию, мы бы определили форму дважды - один раз для front-end и один раз для back-end.

Было бы здорово определить форму только один раз: в скрипте Python. Это именно то, что позволяет нам делать Flask-WTF. Мы определим форму только один раз в сценарии Python, а затем мы предоставим Flask-WTF для создания HTML-кода формы для нас. Все дело в том, чтобы отделить презентацию от контента.

Достаточно болтовни. Давайте сделаем код.

Создание формы

В качестве первого шага давайте вернемся к изолированной среде разработки, которую мы создали в последний раз.

$ cd flaskapp
$ . bin/activate

Теперь, когда мы ввели и активировали нашу среду разработки, мы можем безопасно установить Flask-WTF:

$ pip install flask-wtf

Давайте теперь определим форму в скрипте Python. У нас уже есть route.py, который отображает URL-адреса для функций. Давайте не будем загромождать его несвязанным кодом. Вместо этого создайте новый файл с именем forms.py и поместите его в папку приложения.

app forms.py

from flask.ext.wtf import Form, TextField, TextAreaField, SubmitField
class ContactForm(Form):
  name = TextField("Name")
  email = TextField("Email")
  subject = TextField("Subject")
  message = TextAreaField("Message")
  submit = SubmitField("Send")

Мы только что создали форму. Что мы сделали? Во-первых, мы импортировали несколько полезных классов из Flask-WTF - базового класса Form, текстового поля, поля textarea для многострочного ввода текста и кнопки отправки. Затем мы создали новый класс с именем ContactForm, наследующий от базового класса Form. Затем мы создали каждое поле, которое мы хотим увидеть в контактной форме. Вместо написанияName в файле HTML вы пишете name = TextField («Имя»).

Использование формы

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

Это фрагментированный раздел, и это может быть немного запутанным. Но держись со мной, и мы справимся.

В качестве первого шага откройте route.py и импортируйте нашу вновь созданную форму, добавив из форм импорт ContactForm в начале скрипта.

app routes.py

from flask import Flask, render_template
from forms import ContactForm
Вы можете предотвратить атаку CSRF, убедившись, что представление формы происходит из вашего веб-приложения.

Затем настройте Flask-WTF для обработки эксплойта безопасности, известного как подделка запроса на межсайтовый запрос (CSRF). В идеальном мире ваш сервер будет обрабатывать только формы, принадлежащие вашему веб-приложению. Другими словами, ваш сервер будет обрабатывать и проверять только созданные формы. Однако злоумышленник может создать форму на своем собственном веб-сайте, заполнить ее вредоносной информацией и отправить ее на ваш сервер. Если ваш сервер принимает эту вредоносную информацию, всевозможные плохие вещи могут произойти дальше.

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

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

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

app routes.py

from flask import Flask, render_template, request, flash
from forms import ContactForm
app = Flask(__name__)
app.secret_key = 'development key'

Здесь, в шестой строке, я установил секретный ключ в «ключ разработки». Не стесняйтесь сделать ваш более сложным, длинным и буквенно-цифровым.

Теперь, когда мы импортировали и настроили нашу контактную форму, мы можем использовать ее в сопоставлении URL-адресов в routes.py. Давайте продолжим и создадим это сопоставление URL.

app routes.py

@app.route('/contact')
def contact():
  form = ContactForm()
  return render_template('contact.html', form=form)

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

Тем не менее у нас есть еще одна работа. Рисунок 1 показал, что если на сервер отправляется запрос GET, веб-страница, содержащая форму, должна быть загружена и загружена в браузере. Если сервер получает запрос POST, функция должна захватывать данные поля формы и проверять, действительно ли она действительна. В терминах Python эта логика может быть выражена в инструкции if... else. Существует класс Flask для различения запросов GET и POST, поэтому давайте начнем с импорта этого класса в начале route.py и добавим логику if... else в функцию contact ().

app routes.py

from flask import Flask, render_template, request
.
.
.
@app.route('/contact', methods=['GET', 'POST'])
def contact():
  form = ContactForm()
  if request.method == 'POST':
    return 'Form posted.'
  elif request.method == 'GET':
    return render_template('contact.html', form=form)

Мы уже импортировали класс Flask и render_template () в предыдущей статье, поэтому здесь мы импортируем еще один класс с именем класса. запрос определяет, является ли текущий HTTP-метод GET или POST. Далее следует логика if... else для функции contact () (строки 9-13).

В случае запроса POST будет возвращена строка, указывающая, что форма была отправлена.

Эта строка является временным заполнителем, и мы заменим ее реальным кодом на последнем этапе этой статьи. В противном случае, если запрос использует GET, мы возвращаем веб-шаблон contact.html, который содержит форму.

Следующий шаг - создать веб-шаблон contact.html и поместить его в папку шаблонов.

шаблоны приложений contact.html

{% extends "layout.html" %}
{% block content %}
  <h2>Contact</h2>
  <form action="{{ url_for('contact') }}" method=post>
    {{ form.hidden_tag() }}
    {{ form.name.label }}
    {{ form.name }}
    {{ form.email.label }}
    {{ form.email }}
    {{ form.subject.label }}
    {{ form.subject }}
    {{ form.message.label }}
    {{ form.message }}
    {{ form.submit }}
  </form>
{% endblock %}

Как и в случае с home.html и about.html, шаблон contact.html расширяет layout.html и заполняет блок «content» собственным текстом. Сначала мы указываем, куда отправить данные формы при отправке, установив атрибут действия элемента

в функцию contact (), которую мы создали в route.py (строка 5). Затем мы позволяем движку шаблонов Jinja2 генерировать большую часть формы для нас (строки 6-20). Мы начнем с вставки скрытого тега в строку 6 для защиты от эксплойтов CSRF. Наконец, мы добавляем каждую метку и поле формы.

Теперь мы готовы видеть результат всей нашей работы. Просто введите следующее:

$ python routes.py

Затем перейдите по адресу http: localhost: 5000 в свой любимый веб-браузер.

Загружена страница контакта, содержащая форму. Заполните поля формы и нажмите кнопку «Отправить». Вы увидите страницу, которая выглядит так:

Потрясающие! Представление формы работает.

Давайте быстро рассмотрим все, что мы сделали в этом разделе:

Мы вводим URL-адрес http: localhost: 5000 в адресную строку браузера. Запрос GET попадает на route.py, где URL-адрес сопоставляется с функцией contact (). Выполняется функция contact (), где переменная с именем, содержащая полезный экземпляр класса ContactForm, отправляется на веб-шаблон contact.html. contact.html создает HTML-форму контакта. Представленный HTML отправляется обратно на route.py. route.py отправляет HTML обратно в браузер, и мы видим контактную страницу, содержащую форму. Мы заполняем контактную форму и отправляем ее, нажав кнопку «Отправить». Запрос POST называет route.py, где URL-адрес сопоставляется с функцией contact (). Функция contact () выполняется еще раз, на этот раз после потока if... else для запроса HTTP POST. Строка «Форма отправлена». отправляется обратно в браузер, что дает нам экран выше.

- Контрольная точка: 05_contact_form -

Это классно, но контактная форма выглядит уродливой. Давайте сделаем это лучше, добавив CSS. Откройте main.css и добавьте следующие правила:

static css main.css

/* Contact form */
form label {
  font-size: 1.2em;
  font-weight: bold;
  display: block;
  padding: 10px 0;
}
form input#name,
form input#email,
form input#subject {
  width: 400px;
  background-color: #fafafa;
  -webkit-border-radius: 3px;
     -moz-border-radius: 3px;
          border-radius: 3px;
  border: 1px solid #cccccc;
  padding: 5px;
  font-size: 1.1em;
}
form textarea#message {
  width: 500px;
  height: 100px;
  background-color: #fafafa;
  -webkit-border-radius: 3px;
     -moz-border-radius: 3px;
          border-radius: 3px;
  border: 1px solid #cccccc;
  margin-bottom: 10px;
  padding: 5px;
  font-size: 1.1em;
}
form input#submit {
  display: block;
  -webkit-border-radius: 3px;
     -moz-border-radius: 3px;
          border-radius: 3px;
  border:1px solid #d8d8d8;
  padding: 10px;
  font-weight:bold;
  text-align: center;
  color: #000000;
  background-color: #f4f4f4;
  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f4f4f4), color-stop(100%, #e5e5e5));
  background-image: -webkit-linear-gradient(top, #f4f4f4, #e5e5e5);
  background-image: -moz-linear-gradient(top, #f4f4f4, #e5e5e5);
  background-image: -ms-linear-gradient(top, #f4f4f4, #e5e5e5);
  background-image: -o-linear-gradient(top, #f4f4f4, #e5e5e5);
  background-image: linear-gradient(top, #f4f4f4, #e5e5e5);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=#f4f4f4, endColorstr=#e5e5e5);
}
form input#submit:hover{
  cursor: pointer;
  border:1px solid #c1c1c1;
  background-color: #dbdbdb;
  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#dbdbdb), color-stop(100%, #cccccc));
  background-image: -webkit-linear-gradient(top, #dbdbdb, #cccccc);
  background-image: -moz-linear-gradient(top, #dbdbdb, #cccccc);
  background-image: -ms-linear-gradient(top, #dbdbdb, #cccccc);
  background-image: -o-linear-gradient(top, #dbdbdb, #cccccc);
  background-image: linear-gradient(top, #dbdbdb, #cccccc);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=#dbdbdb, endColorstr=#cccccc);
}

Вернитесь в браузер и обновите контакт http: localhost: 5000, чтобы увидеть результат CSS.

Это выглядит намного лучше. Перейдем к формированию проверки.

- Контрольная точка: 06_contact_styling -

Проверка данных формы

Теперь пользователь может посетить контакт URL и заполнить форму. Но что произойдет, если пользователь неправильно заполняет форму? Нам нужно проверить ввод пользователя, чтобы он не вызывал проблем на последующих этапах.

Проверка формы выполняется с помощью валидаторов формы. К счастью, Flask-WTF поставляется с множеством полезных встроенных валидаторов, которые мы можем использовать сразу. Мы помещаем эти валидаторы в определение класса ContactForm в forms.py.

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

app forms.py

from flask.ext.wtf import Form, TextField, TextAreaField, SubmitField, validators, ValidationError
class ContactForm(Form):
  name = TextField("Name",  [validators.Required()])
  email = TextField("Email",  [validators.Required()])
  subject = TextField("Subject",  [validators.Required()])
  message = TextAreaField("Message",  [validators.Required()])
  submit = SubmitField("Send")

Начнем с импорта валидаторов и ValidationError из Flask-WTF. Это дает нам доступ к встроенным валидаторам Flask-WTF. Затем мы добавляем [validators.Required ()] в каждое поле формы, чтобы проверить его присутствие. Обратите внимание, что этот валидатор находится внутри списка Python, что означает, что мы можем легко добавить в этот список еще несколько валидаторов.

Далее, давайте потребуем, чтобы адреса электронной почты соответствовали шаблону user@example.com, добавив средство проверки электронной почты в поле электронной почты.

app forms.py

from flask.ext.wtf import Form, TextField, TextAreaField, SubmitField, validators, ValidationError
class ContactForm(Form):
  name = TextField("Name",  [validators.Required()])
  email = TextField("Email",  [validators.Required(), validators.Email()])
  subject = TextField("Subject",  [validators.Required()])
  message = TextAreaField("Message",  [validators.Required()])
  submit = SubmitField("Send")

Это делает это для нашей проверки формы.

- Контрольная точка: 07_form_validations -

Мигающие сообщения об ошибках

Оглядываясь на рисунок 1, если какая-либо проверка проверки не удалась, страница контакта должна перезагрузиться с сообщением об ошибке, чтобы пользователь мог исправить ошибку и повторить попытку. Это сообщение об ошибке должно появляться только в том случае, если проверка не удалась и исчезла, когда ошибка была исправлена.

Наш следующий шаг заключается в том, чтобы отправить такое временное сообщение об ошибке пользователю, когда проверка не удалась. Flask делает это очень легко, используя функцию flash (). Начнем с открытия route.py и импорта функции Flask flash () в начале скрипта.

app routes.py

from flask import Flask, render_template, request, flash

После отправки контактной формы POST на сервер любой отказ проверки должен перезагрузить форму с полезным сообщением об ошибке. В противном случае входные данные могут использоваться для дальнейшей обработки. И снова эта логика может быть выражена в выражении if... else. Давайте добавим эту, если... else логику к функции contact () внутри if request.method == 'POST': block.

app routes.py

@app.route('/contact', methods=['GET', 'POST'])
def contact():
  form = ContactForm()
  if request.method == 'POST':
    if form.validate() == False:
      flash('All fields are required.')
      return render_template('contact.html', form=form)
    else:
      return 'Form posted.'
  elif request.method == 'GET':
    return render_template('contact.html', form=form)

Если какая-либо проверка проверки не выполняется, form.validate () будет False. Сообщение об ошибке Все поля обязательно будут отправлены на адрес contact.html. В противном случае мы увидим, что временная строка заполнителя заполнена, указав, что форма была успешно отправлена.

Далее, давайте изменим contact.html, чтобы он мог получать и отображать эти временные сообщения об ошибках. См. Следующий блок:

{% for message in get_flashed_messages() %}
  <div class="flash">{{ message }}</div>
{% endfor %}

Функция get_flashed_messages () вытягивает все свернутые сообщения и возвращает их. Затем мы просто показываем каждое запрограммированное сообщение, используя цикл Jinja2 for. Добавьте этот блок кода в contact.html после

Обратитесь к

и перед тегом
.

шаблоны приложений contact.html

{% extends "layout.html" %}
{% block content %}
  <h2>Contact</h2>
  {% for message in get_flashed_messages() %}
    <div class="flash">{{ message }}</div>
  {% endfor %}
  <form action="{{ url_for('contact') }}" method=post>
    {{ form.hidden_tag() }}
    {{ form.name.label }}
    {{ form.name }}
    {{ form.email.label }}
    {{ form.email }}
    {{ form.subject.label }}
    {{ form.subject }}
    {{ form.message.label }}
    {{ form.message }}
    {{ form.submit }}
  </form>
{% endblock %}

Наконец, давайте добавим правило CSS в main.css, чтобы проблесковые сообщения об ошибках выглядели красиво.

main.css

/* Message flashing */
.flash {
  background-color: #FBB0B0;
  padding: 10px;
  width: 400px;
}

Откройте ваш браузер и посетите контакт http: localhost: 5000. Оставьте все поля пустыми и нажмите «Отправить», чтобы проверить, работает ли проверка формы и сообщение об ошибке.

Это мило! Мы успешно отправили сообщение об ошибке в нашу контактную форму, если проверка проверки не прошла.

- Контрольная точка: 08_error_message_flashing -

Но мы не закончили; мы можем сделать немного лучше. Вместо того, чтобы иметь одно общее сообщение об ошибке для всех неудачных проверок проверки, было бы лучше иметь конкретное сообщение об ошибке для каждой неудачной проверки проверки. Например, если пользователь забывает заполнить поле темы, будет высвечиваться специальное сообщение об ошибке «Пожалуйста, введите тему». Аналогичным образом, если пользователь забывает заполнить свое имя, мы запустим конкретное сообщение об ошибке, в котором говорится: «Введите свое имя». Мы можем сделать это довольно легко, поэтому давайте начнем с написания конкретных сообщений об ошибках внутри каждого валидатора в forms.py.

app forms.py

from flask.ext.wtf import Form, TextField, TextAreaField, SubmitField, validators, ValidationError
class ContactForm(Form):
  name = TextField("Name",  [validators.Required("Please enter your name.")])
  email = TextField("Email",  [validators.Required("Please enter your email address."), validators.Email("Please enter your email address.")])
  subject = TextField("Subject",  [validators.Required("Please enter a subject.")])
  message = TextAreaField("Message",  [validators.Required("Please enter a message.")])
  submit = SubmitField("Send")

Мы просто пишем конкретные сообщения об ошибках внутри каждого валидатора. Затем давайте модифицируем contact.html для получения и отображения этих конкретных сообщений об ошибках. Раньше мы полагались на функцию get_flashed_messages (), чтобы вытащить проблескивые сообщения об ошибках и зациклились над ними, чтобы отобразить их. Давайте заменим этот блок на этот:

{% for message in form.name.errors %}
  <div class="flash">{{ message }}</div>
{% endfor %}
{% for message in form.email.errors %}
  <div class="flash">{{ message }}</div>
{% endfor %}
{% for message in form.subject.errors %}
  <div class="flash">{{ message }}</div>
{% endfor %}
{% for message in form.message.errors %}
  <div class="flash">{{ message }}</div>
{% endfor %}

Здесь мы используем атрибут errors для каждого поля формы, чтобы вытащить конкретные сообщения об ошибках и перебрать их через цикл Jinja2 for для их отображения.

Соединяя все это, contact.html теперь выглядит следующим образом:

app templates contact.html

{% extends "layout.html" %}
{% block content %}
  <h2>Contact</h2>
  {% for message in form.name.errors %}
    <div class="flash">{{ message }}</div>
  {% endfor %}
  {% for message in form.email.errors %}
    <div class="flash">{{ message }}</div>
  {% endfor %}
  {% for message in form.subject.errors %}
    <div class="flash">{{ message }}</div>
  {% endfor %}
  {% for message in form.message.errors %}
    <div class="flash">{{ message }}</div>
  {% endfor %}
  <form action="{{ url_for('contact') }}" method=post>
    {{ form.hidden_tag() }}
    {{ form.name.label }}
    {{ form.name }}
    {{ form.email.label }}
    {{ form.email }}
    {{ form.subject.label }}
    {{ form.subject }}
    {{ form.message.label }}
    {{ form.message }}
    {{ form.submit }}
  </form>
{% endblock %}

Вернитесь в браузер, перейдите на контакт http: localhost: 5000 и нажмите «Отправить». Не забудьте оставить все поля формы пустыми.

Отлично! У пользователя теперь есть полезные сообщения об ошибках, если он совершает ошибку.

- Контрольная точка: 09_specific_message_flashing -

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


Flask-Mail

Flask-Mail - это флеш-расширение, которое позволяет отправлять электронные письма из вашего приложения Flask. Вышеуказанные шаги аналогичны тем, которые мы использовали для использования Flask-WTF.

Давайте начнем с установки Flask-Mail.

$ pip install flask-mail

Конфигурирование Flask-Mail

Далее, позволяет импортировать Flask-Mail в routes.py и настраивать его, чтобы мы могли начать использовать его.

app routes.py

from flask import Flask, render_template, request, flash
from forms import ContactForm
from flask.ext.mail import Message, Mail
mail = Mail()
app = Flask(__name__)
app.secret_key = 'development key'
app.config["MAIL_SERVER"] = "smtp.gmail.com"
app.config["MAIL_PORT"] = 465
app.config["MAIL_USE_SSL"] = True
app.config["MAIL_USERNAME"] = 'contact@example.com'
app.config["MAIL_PASSWORD"] = 'your-password'
mail.init_app(app)

Сначала мы импортируем классы Message и Mail из Flask-Mail (строка три). Мы будем использовать класс Message для создания нового сообщения электронной почты и класса Mail для отправки электронной почты. Затем мы создаем почтовую переменную, содержащую полезный экземпляр класса Mail (строка 5).

Затем мы настраиваем Flask-Mail с несколькими настройками SMTP-сервера (строки 11-15). Я использовал настройки SMTP-сервера Gmail здесь, но вы можете легко использовать своего любимого поставщика электронной почты. Просто выполните поиск настроек SMTP, и вы будете установлены.

Например, если вы хотите использовать Yahoo! Почта, просто найдите «настройки сервера почты yahoo mail smtp» и обновите конфигурацию.

Обязательно введите реальный адрес электронной почты и пароль в app.config ["MAIL_USERNAME"] и app.config ["MAIL_PASSWORD"] соответственно. Это будет учетная запись, с которой вы будете отправлять электронную почту.

Наконец, мы добавляем почту в наше приложение Flask, чтобы мы могли начать использовать его (строка 17).

Вероятно, вы видели, как группы используют контактные адреса электронной почты, такие как contact@example.com или support@example.com. Если у вас есть собственный домен и вы можете создать новый контактный адрес электронной почты, включите этот адрес электронной почты в app.config ["MAIL_USERNAME"]. В противном случае вы можете использовать свой личный адрес электронной почты, чтобы посмотреть, как это работает.

Отправка электронной почты

Теперь, когда конфигурация завершена, давайте составим новое электронное письмо, содержащее данные контактной формы, и отправьте его. Мы должны отправлять только электронное письмо, если форма была отправлена, и все проверки проверки пройдут. Это означает, что нам нужно работать внутри if request.method == 'POST': блок снова. Мы уже добавили логику внутри if, если form.validate () == False: блок для обработки ошибок проверки. Если все проверки проверки пройдены, form.validate () будет True, и программа войдет в блок else. Поэтому давайте продолжим и добавим логику внутри else: block.

app routes.py

@app.route('/contact', methods=['GET', 'POST'])
def contact():
  form = ContactForm()
  if request.method == 'POST':
    if form.validate() == False:
      flash('All fields are required.')
      return render_template('contact.html', form=form)
    else:
      msg = Message(form.subject.data, sender='contact@example.com', recipients=['your_email@example.com'])
      msg.body = """
      From: %s <%s>
      %s
      """ % (form.name.data, form.email.data, form.message.data)
      mail.send(msg)
      return 'Form posted.'
  elif request.method == 'GET':
    return render_template('contact.html', form=form)

Начнем с составления нового сообщения (строка 10). Класс Message принимает строку темы, адрес «от» и адрес «до». Затем мы собираем данные поля темы контактной формы с помощью form.subject.data и устанавливаем ее как строку темы нового сообщения. Письмо будет отправлено с учетной записи, настроенной в app.config ["MAIL_USERNAME"], так что мы использовали здесь для адреса from. Электронная почта будет отправлена на ваш личный адрес электронной почты, чтобы вы могли получать и отвечать на новые сообщения.

Затем мы пишем само письмо (строки 11-14). Мы включаем имя пользователя, адрес электронной почты и сообщение. Я использую оператор форматирования строк Python% для форматирования электронной почты. И, наконец, мы используем mail.send (msg) для отправки электронной почты (строка 15).

Посмотрим, все ли работает. Посетите сайт http: localhost: 5000, заполните все поля и нажмите «Отправить». Если все пойдет хорошо, вы получите новое письмо от своего приложения Flask.

- Контрольная точка: 10_send_email -

Tidying Up

Наш предпоследний шаг - удалить временную строку-заполнитель «Форма, отправленная». с сообщением, поблагодарив пользователя за отзывы. Это сообщение должно появляться только в том случае, если наше приложение отправляет электронное письмо. И снова эта логика может быть выражена в выражении if... else.

Когда контактная форма была успешно отправлена, мы отправим флаг успеха с route.py на contact.html.

Мы поместим логику if... else внутри contact.html. Если для флага успеха установлено значение Истина, мы отобразим сообщение благодарности. В противном случае мы отобразим контактную форму.

Давайте начнем с route.py внутри функции contact (). Замените временный возврат строки-заполнителя «Форма отправлена». с возвратом render_template ('contact.html', success = True), чтобы отправить флаг успеха в contact.html. Функция contact () теперь выглядит следующим образом:

app routes.py

@app.route('/contact', methods=['GET', 'POST'])
def contact():
  form = ContactForm()
  if request.method == 'POST':
    if form.validate() == False:
      flash('All fields are required.')
      return render_template('contact.html', form=form)
    else:
      msg = Message(form.subject.data, sender='contact@example.com', recipients=['your_email@example.com'])
      msg.body = """
      From: %s &lt;%s&gt;
      %s
      """ % (form.name.data, form.email.data, form.message.data)
      mail.send(msg)
      return render_template('contact.html', success=True)
  elif request.method == 'GET':
    return render_template('contact.html', form=form)

Затем откройте contact.html и добавьте логику if... else. Мы будем использовать синтаксис Jinja2, если... else, чтобы это произошло.

шаблоны приложений contact.html

{% extends "layout.html" %}
{% block content %}
  <h2>Contact</h2>
  {% if success %}
    <p>Thank you for your message. We'll get back to you shortly.</p>
  {% else %}
    {% for message in form.name.errors %}
      <div class="flash">{{ message }}</div>
    {% endfor %}
    {% for message in form.email.errors %}
      <div class="flash">{{ message }}</div>
    {% endfor %}
    {% for message in form.subject.errors %}
      <div class="flash">{{ message }}</div>
    {% endfor %}
    {% for message in form.message.errors %}
      <div class="flash">{{ message }}</div>
    {% endfor %}
    <form action="{{ url_for('contact') }}" method=post>
      {{ form.hidden_tag() }}
      {{ form.name.label }}
      {{ form.name }}
      {{ form.email.label }}
      {{ form.email }}
      {{ form.subject.label }}
      {{ form.subject }}
      {{ form.message.label }}
      {{ form.message }}
      {{ form.submit }}
    </form>
  {% endif %}
{% endblock %}

Начиная с шестой строки {% if success%} означает, что если флаг успеха, отправленный с route.py, установлен в значение True, тогда отобразите

Спасибо за ваше сообщение. Мы скоро свяжемся с вами.

. В противном случае следуйте за ветвью {% else%} и отобразите форму контакта. Синтаксис Jinja2 просит закрыть оператор if... else с {% endif%}, поэтому мы включаем это в конец (строка 45).

- Контрольная точка: 11_success_message -

Наконец, давайте перейдем к контакту http: localhost: 5000 еще раз. Заполните все поля и нажмите «Отправить».

Нашим последним шагом является добавление ссылки на страницу контактов. В предыдущей статье мы добавили эти ссылки в layout.html внутри элемента

. Давайте также сделаем это для страницы контакта (строка 8).

шаблоны приложений layout.html

<header>
  <div class="container">
    <h1 class="logo">Flask App</h1>
    <nav>
      <ul class="menu">
        <li><a href="{{ url_for('home') }}">Home</a></li>
        <li><a href="{{ url_for('about') }}">About</a></li>
        <li><a href="{{ url_for('contact') }}">Contact</a></li>
      </ul>
    </nav>
  </div>
</header>

- Контрольная точка: 12_contact_nav_link -

Откройте браузер и обновите http: localhost: 5000, чтобы увидеть добавленную навигационную ссылку.


Заключение

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

Расширения флэков - это простые, мощные инструменты, расширяющие функциональность вашего приложения на фляже.

Зайдите в Registry Extension Registry, чтобы изучить еще множество расширений, которые вы можете интегрировать в свое приложение.