AJAX и jQuery — Flask (1.1.x) простой пример

пример работы ajax с Flask
Пример работы AJAX с Flask

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 + AJAX + jQuery
Результат работы
Ввод данных  Flask + AJAX + jQuery
Ввод данных
Данные успешно отправлены
Данные успешно отправлены
Пример ошибки

Видео с примером работы Flask + jQuery + AJAX.

Исходники

Готовый пример можно скачать с github

git clone https://github.com/newivan/simply-ajax