Раньше я использовал активно связку jQuery для отправки Ajax запроса на сервер. Например так обрабатывал форму обратной связи или онлайн заказ товара.
Время не стоит на месте с использованием библиотеки VueJS я познакомился с библиотекой axios. И стал использовать не только в проектах VueJS но и просто с Flask и Django.
Flask + axios
Напишу подробно, с начало создаю виртуальное окружение, затем ставлю Flask.
mkdir flask-axios
cd flask-axios
python3 -m venv venv
source venv/bin/activate
pip install pip --upgrade
pip install Flask==2.0.1
Далее создаю директорию templates и шаблоны base.html, index.html, файл проекта app.py и дополнительные файлы app.js в директории static.
Создаю переменную окружения FLASK_ENV=development для того, что бы запускать проект в режиме отладки (DEBUG). В данном режиме приложение будет автоматический производить рестарт при изменении исходного кода.
Ещё одна переменная окружения FLASK_APP=app.py приложение Flask, запуск по команде flask run.
mkdir -p templates static/js
touch templates/{base,index}.html
touch static/js/callback.js
touch {app,forms}.py
export FLASK_ENV=development
export FLASK_APP=app.py
Сам проект на Flask
Файл app.py
from flask import Flask
from flask import render_template
import json
# форма для обратной сзвязи
from forms import CallBackForm
app = Flask(__name__)
SECRET_KEY = '12345'
app.config['SECRET_KEY'] = SECRET_KEY
@app.route("/")
def index():
form = CallBackForm()
return render_template('index.html',
title="Пример отправки",
form=form)
@app.route("/callback", methods=['POST'])
def callback():
form = CallBackForm()
if form.validate_on_submit():
# функции отправить почту, записать в БД и т. д.
return json.dumps({'success': 'true', 'msg': 'Ждите звонка!'})
else:
# обработать ошибку
return json.dumps({'success': 'false', 'msg': 'Ошибка на сервере!'})
В строке 20 происходит обработка нажатия на кнопку (index.html строка 7).
Благодаря использованию формы, происходит нормальная валидация и недоступные значения успешно обрабатываются.
Форма
Файл forms.py
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import DataRequired
from wtforms.validators import Length
class CallBackForm(FlaskForm):
name = StringField('Имя', validators=[DataRequired()])
phone = StringField('Телефон', validators=[DataRequired(), Length(min=4)])
В сроке 9 параметр Length(min=4) указывает, если количество знаков меньше 4, валидация не пройдёт.
Верстка
Файл base.html в директории templates
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask 2.0.X axios simple - {{ title }}</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
{% block scripts %}
{% endblock scripts %}
</head>
<body>
{% block content %}
{% endblock content %}
</body>
</html>
В сроке 6 и 7 подключаю через cnd — JQuery и Axios.
Не стал для усложнения переписывать проект без JQuery.
Верстка
Файл index.html в директории templates
{% extends "base.html" %}
{% block content %}
<form action="/callback" 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>
{% endblock %}
{% block scripts%}
{{ super() }}
<script src="{{ url_for('static', filename='js/callback.js') }}"></script>
{% endblock %}
В строке 4 csrf_token иначе не пройдёт валидацию.
JavaScript
Файл callback.html в директории static/js
/* переопределить поведение кнопки "Отправить" */
$(document).ready(function () {
$("#form1").submit(function( event ) {
CallBackForm("form1", "msg");
event.preventDefault();
});
});
/* отправка данных на сервер по AJAX */
function CallBackForm(form, msg){
let from = new FormData();
from.append('name', $( "#name" ).val());
from.append('phone', $( "#phone" ).val());
from.append('csrf_token', $( "#csrf_token" ).val());
axios({
url: '/callback',
method: 'post',
data: from,
})
.then(function (response) {
$( '#' + msg ).html(response.data.msg);
if (response.data.success == 'true') {
$( "#" + form ).trigger('reset');
}
else
{
alert("Что-то пошло не так!");
console.log("Ошибка");
}
})
.catch(function (error) {
console.log(error);
});
};
В строках 12-14 добавляются данные из формы для отправки. Строка 21 записывает ответ от сервера (файл app.py строка 25 или 28) в зависимости от правильности ввода.
Готовый код примера
git clone https://github.com/ivanov-s/flask-axios.git