Django 5 для начинающих

Прогресс по курсу:  9/1004

4.1 Формы в Django
5 из 16 шагов пройдено
0 из 48 баллов  получено

Форма HTML- это группа из одного или нескольких полей (виджетов) на веб-странице, которая используется для получения информации от пользователей для последующей отправки на сервер и представляет собой таким образом гибкий механизм сбора пользовательских данных.

Формы несут целый набор виджетов для ввода различных типов данных: текстовые поля, флажки, переключатели, установщики дат и пр. Формы являются относительно безопасным способом взаимодействия пользовательского клиента и сервера, поскольку позволяют отправлять данные в РОSТ-запросах, применяя защиту от межсайтовой подделки запроса (Cross Site Request Forgery, CSRF).

Из материалов этого раздела вы узнаете:

  • что такое формы Django и для чего они нужны;
  • как применять в формах РОSТ-запросы;
  • какие поля можно использовать в формах;
  • как можно выполнить настройку формы и ее полей;
  • как можно изменить внешний вид формы;
  • как осуществляется проверка (валидация) данных в формах;
  • как можно добавить стили к полям формы.

 

Создадим проект Course_ThirdProject и приложение с именем crud и рассмотрим работу с объектами модели данных при чтении, записи, редактировании и удалении записей. Не забываем добавлять наше приложение в settings.py и также добавить папку с шаблонами.

 

Определение форм

Если вы планируете создавать сайты и приложения, которые принимают и сохраняют данные от пользователей, вам необходимо использовать формы. Django предоставляет широкий набор инструментов для этого. Формы в HTML позволяют пользователю вводить текст, выбирать опции, изменять различные объекты, загружать рисунки на страницы и т. п., а потом отправлять эту информацию на сервер.

Django предоставляет различные возможности по работе с формами. Можно определить функциональность форм в одном месте и затем использовать их многократно в разных местах. При этом упрощается проверка корректности данных, связывание форм с моделями данных и многое другое.

Каждая форма определяется в виде отдельного класса, который расширяет класс forms.Form. Классы размещаются внутри проекта, где они используются. Нередко они помещаются в отдельный файл, который называется, к примеру, forms.py. Однако формы могут размещаться и внутри уже имеющихся в приложении файлов - например, в views.py или models.py.

Создадим в приложении crud новый файл forms.py и поместим в него следующий код:

from django import forms


class UserForm(forms.Form):
    name = forms.CharField()
    age = forms.IntegerField()

Здесь класс формы называется UserForm. В нем определены два поля:

  • Поле name (имя) имеет тип forms.CharField и будет генерировать текстовое поле: input type="text".
  • Поле age (возраст) имеет тип forms.IntegerField и будет генерировать числовое поле: input type="number".

То есть первое поле предназначено для ввода текста, а второе - для ввода чисел.

Далее в файле views.py мы можем определить следующий код для функции index():

from django.shortcuts import render
from .forms import UserForm
 
def index(request):
    userform = UserForm()
    return render(request, 'index.html', {'form': userform})

Здесь созданный нами объект формы передается в шаблон index.html в виде переменной form.

Теперь изменим шаблон index.html следующим образом:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Учу Django</title>
</head>
<body>
    <table>
        {{ form.as_table }}
    </table>
</body>
</html>


Теперь осталось нам связать представление с маршрутами, для этого в главный urls.py проекта добавим следующий код:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('crud.urls')),
]

В этом коде мы импортируем маршруты из нашего приложения.


Теперь создадим файл маршрутов в папке приложения, для этого в папке crud создадим файл urls.py и добавим следующий код:

from django.urls import path
from crud import views

urlpatterns = [
    path('', views.index),
]


Теперь запустим наш проект командой :

python manage.py runserver


А затем откроем наш сайт по адресу http://127.0.0.1:8000:


А в HTML коде страницы у нас будет следующий код:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title>Учу Django</title>
    </head>
    <body>
        <table>
            <tr>
                <th><label for="id_name">Name:</label></th>
                <td><input type="text" name="name" required id="id_name"></td>
            </tr>
            <tr>
                <th><label for="id_age">Age:</label></th>
                <td><input type="number" name="age" required id="id_age"></td>
            </tr>
        </table>
    </body>
</html>

В обрамленные рамками поля пользователь может вводить свои данные. Следует заметить, что в модуле forms.py мы задали только идентификаторы полей name и age и не задавали метки полей (label), которые будут выводиться на экран. В Django эти метки генерируются автоматически. В частности, как можно видеть, для наших двух полей были сгенерированы метки: Name и Age.

По умолчанию в Django в качестве метки берется имя поля, и его первый символ меняется на заглавную букву. С одной стороны, такой прием избавляет программиста от дополнительного задания значения для метки поля, но это не всегда удобно.

Часто требуется задавать более осмысленные и достаточно длинные значения для меток полей и на языке, отличном от английского. Однако желательно избегать использования кириллицы и других символов, отличных от ASCII, в определении имен полей. Это впоследствии может привести к некорректному отображению информации, когда приложение будет развернуто на внешнем веб-ресурсе.

В Django имеется другая возможность задания метки для поля - с помощью параметра label.

Немного изменим содержимое файла forms.py и поместим в него следующий код:

from django import forms


class UserForm(forms.Form):
    name = forms.CharField(label='Имя')
    age = forms.IntegerField(label='Ваш возраст?')

Здесь мы задали имя поля латиницей, а метку поля определили кириллицей. В результате мы изменили названия наших полей инпут.

Кроме параметра label, поля форм Django, имеют еще ряд параметров, которые разработчик может определять программным способом. Их мы рассмотрим более подробно в следующих шагах.


  • Комментариев
Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий
Комментарий закреплён

Понравилась задача, тест или урок? Поставьте лайк, поддержите курс. Ваша поддержка очень важна для нас.

Напомните, папку с шаблонами на данном этапе мы создаем конкретно в проекте crud и указываем путь к ней в настройках в переменной templates? Или тут говорится об общей папке с шаблонами в корне проекта? 

И второй вопрос, только сейчас задумался о структуре, помогите уложить кашу в голове.

1. Мы сначала создаем проект
2. потом устанавливаем джанго
3. потом создаем проект с файлом __init__  - это и есть тот самый проект джанго? В пункте 1 это общий проект, в который так же может входить проект на джанго, верно? Наш джанго-проект это всего лишь подпроект другого проекта? Почему тогда приложения устанавливаются не в джанго-проект а в основной? Извините за тавтологию, просто основной проект и джанго называются одинаково.

Или второй вариант, исходя из рисунка в степе 2.3 это все джанго-проект, просто в директории с файлом init хранятся его основные настройки? Таким образом наш проект становится джанго-проектом когда мы прописываем 

​​​​​​​django-admin startproject Course_ThirdProject .

?

@Георгий_Тимофеев, Мы говорим всегда об общей папке шаблонов, она находится в корне проекта. Просто все очень сильно отличается от того, в каком редакторе кода мы работаем. PyCharm Pro делает это все сам, и создает проект Django с установленным фреймворком. Но когда мы работаем в PyCharm CE, то мы можем создать лишь простой проект Python, и установив в него Django, после можно сказать что он становится уже проектом Django.

По поводу структуры. Мы создаем проект в редакторе кода, чтобы работать в виртуальной среде. Например в этой лекции видно, что мы создали проект в PyCharm CE, и когда вводим команду установки джанго, она устанавливается уже в виртуальную среду (venv). Правильно говорить что есть проект Django, а есть приложения в этом проекте (crud, blog и тд).

По поводу пункта 3 не совсем понял, что такое создаем проект с файлом __init__. Этот файл служит для того, чтобы сообщить питону, что эта папка с этим файлом является пакетом Python, и ее можно подключать из других файлов. Он содержит код инициализации пакета. Папка с settings.py, главным urls.py, asgi, wsgi файлами, это главная папка как контейнер Django.

По поводу пункта 3 не совсем понял, что такое создаем проект с файлом __init__.

Я просто не знал как описать папку c init, settings и тд, теперь понял что это контейнер Django) 

В целом стало понятней, спасибо за разъяснения.

@Георгий_Тимофеев, директория шаблонов находится в корневой директории проекта PyCharm, в той что находится файл manage.py.

1. сначала создаём новый проект PyCharm, при этом будет создана директория(с названием проекта PyCharm) и в ней будет установлено виртуальное окружение(директория venv) и оно будет активировано.

2. устанавливаем Django.

3. создаём новый проект Django, например: ​​​​​​​django-admin startproject Course_ThirdProject ., при этом в директории проекта PyCharm будет создана директория проекта Django: Course_ThirdProject , в ней будут системные файлы проекта Django, один из которых файл настроек - settings.py.

Файлы __init__.py создавать не нужно, они будет создан автоматически при создании проекта и приложения.

@Дмитрий_Селезнев,  исходя из пункта 3 можем ли мы в директории проекта PyCharm создать еще один проект помимо джанго? Или создание проекта джанго определяет весь проект как джанго-проект? 

@Георгий_Тимофеев, нет, в одну директорию не установить два проекта Django:

@Дмитрий_Селезнев, понял, спасибо большое

У меня по сути все идентично и все работает, но почему-то в HTML коде появились странные отступы, где может быть причина такого поведения (и в мозиле и в хроме одинаковое поведение)?)

Я не очень понимаю, как работает окружение. Мы можем в проекте использовать окружение другого проекта? Зачем я каждый раз ставлю джанго (к вопросу о не повторяться)?  В скрипте activate абсолютный путь к папке проекта, поэтому напрямую его нельзя использовать с новым проектом.  Я бы установила один раз джанго в систему, а не каждый раз в  новое окружение. Пока строго следую инструкциям, для меня сейчас важнее разобраться с Django.

@Ольга_Миронова, после активации виртуального окружения, библиотеки питона будут устанавливаться локально, в проект. Это позволит в дальнейшем избежать конфликтов библиотек и замусоривания системы. И в дальнейшем позволит сформировать файл зависимостей проекта, который необходим для переноса проекта на другой компьютер или для деплоя проекта. Можно выполнить глобальную установку Django и работать без виртуального окружения. Только лучше сразу привыкать работать с виртуальным окружением, установка Django не занимает долго времени - выполняется практически мгновенно.

  • @Дмитрий_Селезнев, Спасибо! Все поняла. Это действительно удобно. Но сейчас за меня это делает pycharm. А я до сегодняшнего дня при конфликтах изменяла .profile и новый вход в систему. А получается можно под конфликтующие приложения настроить разные окружения и активировать их перед запуском) Спасибо!   

@Ольга_Миронова, тем более PyCharm сам активирует виртуальное окружение при открытии PyCharm-проекта, не нужно вручную каждый раз это делать. Требуется только один раз выполнить команду установки Django, создать Django-проект и приложение и спокойно работать.

Изменен Дмитрий Селезнев

При создании по инструкции формы html разметка страницы отличается от вышеуказанного кода (код скопировал с режима разработчика сайта после запуска сайта ):

<head>
    <meta charset="UTF-8">
    <title>Учу Django</title>
</head>
<body>
<div>
    <label for="id_name">Ваше имя:</label>

<input type="text" name="name" required="" id="id_name">
    </div><div>
    <label for="id_age">Ваш возраст:</label>

<input type="number" name="age" required="" id="id_age">
       
    </div><table>
    
</table>

</body>

То есть форма реализуется блоками <div>, а не строками <tr>. Хотел уточнить почему так получается?

Изменен Евгений Епишкин

@Евгений_Епишкин, Похоже что Django 4 по умолчанию выводит поля формы как таблицы, а Django 5 выводит уже как блоки div. Чуть изменили код в лекции, чтобы у всех он был одинаков.

Спасибо

В последнем примере изменили label для полей. Но у меня он по прежнему остается как Name и Age.
Где я мог допустить ошибку? Сервер перезапускал)

@Василий_Шопин, код шаблона должен быть такой:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Учу Django</title>
</head>
<body>
    <table>
        {{ form.as_table }}
    </table>
</body>
</html>

@Дмитрий_Селезнев

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>Учу Django</title>
</head>
<body>
<table>
    <tr>
        <th><label for="id_name">Name:</label></th>
        <td><input type="text" name="name" required id="id_name"></td>
    </tr>
    <tr>
        <th><label for="id_age">Age:</label></th>
        <td><input type="number" name="age" required id="id_age"></td>
    </tr>
</table>
</body>
</html>

Вот этот код т.е под капотом будет?

Изменен Василий Шопин

@Василий_Шопин, этот код будет в ответе сервера - то есть Django преобразует код шаблона в этот html код.