Flask не стоит на месте. Решил дополнить пример обработки формы при помощи AJXA. Я использую данный код для обработки формы заказа звонка на сайтах. Приведу список requirements.txt (для гарантии работы кода лучше использовать его). Версия Python 3.8.2.
Установка Flask и библиотек
# настройка виртуального окружения python, всё как всегда :)
python3 -m venv venv
# активация окружения
source venv/bin/activate
# обновления pip
pip install pip --upgrade
# установка всего необходимого
pip install -r requirements.txt
Flask==1.1.2 Flask-WTF==0.14.3
Подготовка
Необходимо создать структуру проекта, лучше сделать для примера как я привел ниже:
# структура проекта
.
├── app.py
├── forms.py
├── requirements.txt
└── templates
├── base.html
└── index.html
Создать директорию templates, и два файла в ней base.html и index.html.
mkdir templates
touch templates/base.html
touch templates/index.html
Содержимое файла base.html, всё как обычно, стоить отметить в строке 6 подключение библиотеки jQuery чере cnd google.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask AJAX + jQuery simple - {{ title }}</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
{% block content %}
{% endblock content %}
<div id="msg"></div>
</body>
</html>
Так же создаю файл с index.html который расширяет base.html.
Строки 3-8 содержат форму.
Строка 10 содержит div с id=»msg» в него будет записан ответ с сервера.
Сроки 13-18 код который связывает события «submit» кнопки из формы, с функцией отправки данных через ajax, в качестве параметра передается id формы и id элемента для записи ответа (без #). В данном случаи «form1» и «msg». event.preventDefault() — отменяет стандартное поведение.
Строки 23-45 функция sendAjaxForm отправляет данные формы (form1).
{% extends "base.html" %}
{% block content %}
<form action="/send" id="form1" method="post">
{{ form.csrf_token }}
{{ form.name.label }} {{ form.name() }}
{{ form.phone.label }} {{ form.phone() }}
<input type="submit" value="Отправить"/>
</form>
<div id="msg"></div>
<script>
/* переопределить поведение кнопки "Отправить" */
$(document).ready(function () {
$("#form1" ).submit(function( event ) {
sendAjaxForm("form1", "msg");
event.preventDefault();
});
});
/* отправка формы через ajax */
function sendAjaxForm(form_ajax, msg) {
var form = $("#" + form_ajax);
$.ajax({
type: form.attr('method'),
url: form.attr('action'),
data: form.serialize(),
success: function (response) {
var json = jQuery.parseJSON(response);
$('#' + msg).html(json.msg);
if (json.success == 'true') {
form.trigger('reset');
}
else
{
alert("Что-то пошло не так!");
console.log("Ошибка");
}
},
error: function (error) {
console.log(error);
}
});
}
</script>
{% endblock %}
Подробней про функцию sendAjaxForm.
Что бы код можно было использовать для различных форм, я сделал передачу параметром формы и сообщения.
Итак, строка 23 просто получаем объект формы по id (#frim1).
Строка 25 type должен быть GET или POST это метод, беру его из параметров формы (method).
Аналогична строка 26 url должен содержать адрес для обработки запроса, в данном случаи так же берётся из формы (action). (её обрабатывает на сервере функция send см. файл app.py строка 22).
Строка 27 данные формы готовятся к отправки на сервер.
Строки 28 если всё прошло успешно, получен ответ от сервера он будет в response.
Строка 29 преобразую данные в объект json для удобства работы.
Строка 30 вывожу ответ в div с id=msg.
Строки 31-33 — успех, очищаю форму.
Строки 34-38 — что то не так, ошибка.
Строки 40-42 — если ошибки в запросе на сервер, нет связи, ошибка в url и т. д.
С HTML и JavaScript всё 🙂
Форма Flask файл forms.py
Строки 8-9 параметр DataRequired говорит о том, что они обязательны для заполнения. Length — размер не меньше 4 знаков.
В старых версиях wtf вместо StringField был TextField, сейчас лучше писать StringField. В версии 3.0 TextField перестанет работать.
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import DataRequired
from wtforms.validators import Length
class ContactForm(FlaskForm):
name = StringField('Имя', validators=[DataRequired()])
phone = StringField('Телефон', validators=[DataRequired(), Length(min=4)])
Файл app.py сам проект на Flask
Строка 6 форма обратной связи.
Строка 21 декоратор обработки url «/send».
Строка 22 функция отправки «сообщения».
Строка 24 если валидация успешна, возвращает json с положительным ответом (строка 27) иначе с отрицательным (строка 30).
from flask import Flask
from flask import request
from flask import render_template
import json
# форма для обратной сзвязи
from forms import ContactForm
app = Flask(__name__)
app.config['SECRET_KEY'] = "12345"
@app.route('/', methods=['GET', 'POST'])
def index():
form = ContactForm()
return render_template("index.html",
title="index page",
form=form)
@app.route('/send', methods=['POST'])
def send():
form = ContactForm()
if request.method == "POST":
if form.validate_on_submit():
# отправить почту, записать в БД и т. д.
return json.dumps({'success': 'true', 'msg': 'Ждите звонка!'})
else:
# обработать ошибку
return json.dumps({'success': 'false', 'msg': 'Ошибка на сервере!'})
if __name__ == '__main__':
app.run(debug=True)
Запуск app.py
python3 app.py
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 334-159-801
Результат работы
Видео с примером работы Flask + jQuery + AJAX.
Исходники
Готовый пример можно скачать с github
git clone https://github.com/newivan/simply-ajax