Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Работа с формами Python: Разработка на фреймворке Django

Чтобы реализовать создание и обновление сущности в CRUD, нужно научиться правильно работать с формами. Создавать формы самостоятельно утомительно. Сотни строк одинакового кода, обработка ошибок, защита от атак — всё это придется делать постоянно.

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

Django Forms

Формы Django удобны тем, что можно создать новую форму с нуля или воспользоваться ModelForm, чтобы сохранять содержимое формы в модель.

Django выполняет три отдельные части работы с формами:

  • Подготовка данных для рендеринга
  • Создание HTML-формы для данных
  • Получение и обработка форм и данных от клиента

Для начала работы с формами Django необходимо создать файл forms.py внутри приложения:

hexlet_django_blog
   └── article
      └── forms.py

Теперь добавим следующий код:

from django import forms # Импортируем формы Django

class CommentArticleForm(forms.Form):
    content = forms.CharField(label='Комментарий') # Текст комментария

В этом примере мы определили класс нашей формы с одним полем — content. Данное описание формы при рендеринге даст следующий HTML-вид:

<label for="id_content">Комментарий:</label>
<textarea name="content" cols="40" rows="10" required id="id_content"></textarea>

Код не включает <form> тег или кнопку отправки. В дальнейшем нам нужно самим добавить их в шаблон.

Чтобы форма отображалась, нужно создать представление со следующим содержанием:

from django.shortcuts import render
from .forms import CommentArticleForm

class CommentArticleView(View):

    def get(self, request, *args, **kwargs):
        form = CommentArticleForm() # Создаем экземпляр нашей формы
        return render(request, 'comment.html', {'form': form}) # Передаем нашу форму в контексте

Создадим шаблон с нашей формой:

<form action="{% url 'comment_create' %}" method="post">
    {% csrf_token %}
    <table border="1">
       {{ form }}
    </table>
    <input type="submit" value="Сохранить">
</form>

В шаблоне для отображения формы достаточно указать только {{ form }}. Дальнейшую генерацию и отображение формы Django возьмет на себя. Мы также обязательно добавляем {% csrf_token %} в форму. Данная инструкция встраивает скрытое поле со случайным кодом, который проверяется Django и защищает от CSRF-атак.

Обработка Django Forms

Любую информацию о HTTP-запросе и данные формы можно получить из объекта request. В Django для этого достаточно передать в класс формы request.POST для автоматической обработки переданных данных:

class CommentArticleView(View):

    def post(self, request, *args, **kwargs):
        form = CommentArticleForm(request.POST) # Получаем данные формы из запроса
        if form.is_valid(): # Проверяем данные формы на корректность
            comment = Comment(
                name = form.cleaned_data['content'], # Получаем очищенные данные из поля content
                        # Заполняем оставшиеся поля
                )
            comment.save()

Django ModelForm

Если в приложении есть база данных, то можно предоставить пользователям возможность заполнения некоторых полей самостоятельно. Например, у нас есть модель ArticleComment и мы хотим создать форму, чтобы пользователи смогли оставлять комментарии

from django.db import models

class ArticleComment(models.Model):
    content = models.CharField('content', max_length=100)

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

# forms.py
from django.forms import ModelForm

class ArticleCommentForm(ModelForm):
    class Meta:
        model = ArticleComment
        fields = ['content']

Такой класс при генерации будет иметь все перечисленные поля в атрибуте fields указанной модели в атрибуте model.

Обработка Django ModelForm

Обработка Django ModelForm отличается от Django Forms только тем, что в ModelForm у нас уже есть связь с моделью. Поэтому мы можем после проверки формы сразу перейти к сохранению данных:

class ArticleCommentFormView(View):

    def post(self, request, *args, **kwargs):
        form = ArticleCommentForm(request.POST) # Получаем данные формы из запроса
        if form.is_valid(): # Проверяем данных формы на корректность
            form.save() # Сохраняем форму

Если нам нужно дополнительно заполнить или обработать поля формы, то мы можем указать Django, что данные не нужно сразу сохранять:

class ArticleCommentFormView(View):

    def post(self, request, *args, **kwargs):
        form = ArticleCommentForm(request.POST) # Получаем данные формы из запроса
        if form.is_valid(): # Проверяем данные формы на корректность
            comment = form.save(commit=False) # Получаем заполненную модель
            # Дополнительно обрабатываем модель
            comment.content = check_for_spam(form.data['content'])
            comment.save()

В данном примере мы при помощи commit=False говорим Django, что данные пока сохранять не нужно, и получаем объект нашей модели. После дополнительной обработки модели ее необходимо сохранить с помощью вызова метода .save().


Дополнительные материалы

  1. Документация

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
Обучитесь разработке бэкенда сайтов и веб-приложений — серверной части, которая отвечает за логику и базы данных
10 месяцев
с нуля
Старт 21 ноября

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»