Работа с формами

Отправка форм

Последнее обновление: 20.08.2022

Одной из форм отправки данных на сервер представляет отправка с помощью форм html, обычно в запросе типа POST. В Django в целом можно использовать два подхода для работы с формами. Во-первых, можно работать со стандартными формами html. Во-вторых, Django также предоставляет специальный функционал для работы с формами, который, возможно, в каких-то моментах упрощает работу с данными. В даннной главе рассмотрим оба подхода. А в данной статье посмотрим, как получать данные обычных форм html.

Обычно данные форм передаются на сервер в запросе типа POST. Для получения подобных данных в классе HttpRequest определено свойство POST. Например, пусть у нас есть следующий шаблон index.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
    <h2>User form</h2>
    <form method="post" action="postuser/">
        {% csrf_token %}
        <p>Name:<br> <input name="name" /></p>
        <p>Age:<br> <input name="age" type="number" /></p>
        <input type="submit" value="Send" />
    </form>
</body>
</html>

Здесь определена форма условно для ввода данных пользователя, которая в запросе типа POST (атрибут method="post") отправляет данные по адресу "postuser/" (атрибут action="postuser/").

На форме определены два поля ввода. Первое поле предназначено для ввода имени пользователя. Второе поле - для ввода возроста пользователя.

Также внутри формы используется тег {% csrf_token %}. Он позволяет защитить приложение от CSRF-атак, добавляя в форму в виде скрытого поля csrf-токен. Кроме того, Django по умолчанию требует наличия данного токена в получаемых данных в запросе POST.

Для отправки формы и получения ее данных определим в файле views.py следующие функции:

from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    return render(request, "index.html")

def postuser(request):
    # получаем из данных запроса POST отправленные через форму данные
    name = request.POST.get("name", "Undefined")
    age = request.POST.get("age", 1)
    return HttpResponse(f"<h2>Name: {name}  Age: {age}</h2>")

В представлении index возвращается шаблон, который содержит форму ввода.

В представлении postuser получаем через словарь request.POST отправленные из формы данные. В этом словаре по ключу можно получить значение элемента. При этом в качестве ключей выступает названия полей форм (значения атрибутов name элементов формы):

<input name="age" type="number" />

Так, в данном случае название поля (значение атрибута name) равно "age". Соответственно в request.POST по этому имени мы можем получить его значение:

age = request.POST.get("age", 1)

Если по каким-то причинам данные с ключом "age" в запросе отсутствуют, то возвращается значени по умолчанию - 1.

Далее в файле urls.py свяжем эти функции с маршрутами:

from django.urls import path
from hello import views
 
urlpatterns = [
    path("", views.index),
    path("postuser/", views.postuser),
]

И после получения данных формы они отправляются обратно клиенту:

Отправка форм в веб-приложении на Django и Python

Получение массивов

Усложним задачу и добавим в форму на странице index.html несколько полей, которые будут представлять массив:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
    <h2>User form</h2>
    <form method="post" action="postuser/">
        {% csrf_token %}
        <p>Name:<br /> <input name="name" /></p>
        <p>Age:<br /> <input name="age" type="number" /></p>
        <p>
            Languages:<br />
            <input name="languages" /><br />
            <input name="languages" /><br />
            <input name="languages" /><br />
        </p>
        <input type="submit" value="Send" />
    </form>
</body>
</html>

Здесь практически та же форма, только добавлено три поля для ввода языка программирования. Причем каждое из этих полей имеет одно и то же имя - "languages". Благодаря этому при отправке формы в данных запроса будет сформирован список languages из данных, введенных в эти поля.

В файле views.py изменим функцию postuser для получения массива languages:

from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    return render(request, "index.html")

def postuser(request):
    # получаем из строки запроса имя пользователя
    name = request.POST.get("name", "Undefined")
    age = request.POST.get("age", 1)
    langs = request.POST.getlist("languages", ["python"])
    
    return HttpResponse(f"""
                <div>Name: {name}  Age: {age}<div>
                <div>Languages: {langs}</div>
            """)

Ключевой компонент при получении списка данных из запроса представляет метод getlist(), который работает так же, как и get(), только возвращает список. Если в запросе не окажется данных с ключом languages, то возвращаем список ["python"]

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

Отправка массивов и списков в Django в запросе Post

Подобным образом можно передавать значения массива полей других типов, либо полей, которые представляют набор элементов, например, элемента select, который поддерживает множественный выбор:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
    <h2>User form</h2>
    <form method="post" action="postuser/">
        {% csrf_token %}
        <p>Name: <br />
            <input name="name" />
        </p>
        <p>Age: <br />
            <input name="age" type="number" />
        </p>
        <p>
            Languages:<br />
            <select multiple name="languages">
                <option>Python</option>
                <option>JavaScript</option>
                <option>C++</option>
                <option>Java</option>
             </select>
        </p>
        <input type="submit" value="Send" />
    </form>
</body>
</html>
Получение списков в Django в запросе Post
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850