Работа с формами несколько отличается от получения на сервере данных в теле запроса. Прежде всего необходимо установить модуль python-multipart с помощью команды
pip install python-multipart
Непосредственно в самом FastAPI для получения данных отправленных форм применяется класс fastapi.Form
Пусть у нас будет следующий проект:
В папке public определим файл index.html со следующим кодом:
<!DOCTYPE html>
<html>
<head>
<title>METANIT.COM</title>
<meta charset="utf-8" />
</head>
<body>
<h2>Форма ввода</h2>
<form action="postdata" method="post">
<p>
Name:<br>
<input name="username" />
</p>
<p>
Age:<br>
<input name="userage" type="number" />
</p>
<input type="submit" value="Send" />
</form>
</body>
</html>
Здесь определена простейшая форма для ввода имени и возраста. И по нажатию на кнопку данные отправляются в запросе POST по адресу "postdata".
Для получения данных форм в файле main.py определим следующий код:
from fastapi import FastAPI, Form
from fastapi.responses import FileResponse
app = FastAPI()
@app.get("/")
def root():
return FileResponse("public/index.html")
@app.post("/postdata")
def postdata(username = Form(), userage=Form()):
return {"name": username, "age": userage}
В функции postdata, которая обрабатывает запрос по одноименному пути, через параметры получаем отправленные данные. Причем параметры называются также, как и атрибуты name
у полей формы. А самим параметрам присваивается объект Form.
Класс Form из пакета fastapi предоставляет возможности валидации значений форм с помощью некоторых параметров конструктора:
min_length: устанавливает минимальное количество символов в значении параметра
max_length: устанавливает максимальное количество символов в значении параметра
pattern: устанавливает регулярное выражение, которому должно соответствовать значение параметра
lt: значение параметра должно быть меньше определенного значения
le: значение параметра должно быть меньше или равно определенному значению
gt: значение параметра должно быть больше определенного значения
ge: значение параметра должно быть больше или равно определенному значению
Применим некотрые параметры:
from fastapi import FastAPI, Form
from fastapi.responses import FileResponse
app = FastAPI()
@app.get("/")
def root():
return FileResponse("public/index.html")
@app.post("/postdata")
def postdata(username: str = Form(min_length=2, max_length=20),
userage: int =Form(ge=18, lt=111)):
return {"name": username, "age": userage}
В данном случае параметр username должен иметь не меньше 2 и не больше 20 символов, а параметр userage должен представлять число в диапазоне от 18 (включительно) до 111 (не включая)
С помощью параметра default конструктора Form можно установить значение по умолчанию на случай, если во входящих данных отсуствуют соответствующие значения:
from fastapi import FastAPI, Form
from fastapi.responses import FileResponse
app = FastAPI()
@app.get("/")
def root():
return FileResponse("public/index.html")
@app.post("/postdata")
def postdata(username: str = Form(default ="Undefined", min_length=2, max_length=20),
userage: int =Form(default=18, ge=18, lt=111)):
return {"name": username, "age": userage}
С помощью форм могут отправляться наборы данных. Например, изменим файл index.html следующим образом:
<!DOCTYPE html>
<html>
<head>
<title>METANIT.COM</title>
<meta charset="utf-8" />
</head>
<body>
<h2>Форма ввода</h2>
<form action="postdata" method="post">
<p>
Name:<br>
<input name="username" />
</p>
<p>
Languages:<br>
<input name="languages" /><br><br>
<input name="languages" /><br><br>
<input name="languages" /><br><br>
</p>
<input type="submit" value="Send" />
</form>
</body>
</html>
Здесь на форме определен набор элементов ввода, которые имеют одно и то же имя - "languages". При отправке формы из значений этих элементов будет формироваться набор. Для получения этого набора в коде сервера определим соответствующий параметр как параметр типа list:
from fastapi import FastAPI, Form
from fastapi.responses import FileResponse
app = FastAPI()
@app.get("/")
def root():
return FileResponse("public/index.html")
@app.post("/postdata")
def postdata(username: str = Form(),
languages: list =Form()):
return {"name": username, "languages": languages}
Единственное неудобство, с которым в данном случае можно столкнуться, это оправка пустых строк, как в скриншоте ниже в случае с третьим полев ввода языка: