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

Создание (CRUD) Python: Разработка на фреймворке Django

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

  • Отображение новой формы
  • Отображение формы с подсвеченными ошибками валидации после ее отправки
  • Редирект на страницу после успешной обработки формы. Обычно это редактирование сущности или списка сущностей

Самое интересное здесь это когда пользователь нажал кнопку отправки, данные формы приходят в обработчик формы. Этот обработчик выполняет валидацию — проверку введенных данных. Например, проверяет, что данные в принципе есть — они не пустые. Если данные корректные, то обработка завершается, и пользователя отправляют в другое место. Если нет, то Django должен отработать эту ситуацию и сообщить пользователю о неверно введенных данных.

С точки зрения пользователя, сайт снова отображает форму с подставленными значениями, которые он ввел раньше. Кроме этого, на странице выводятся возникшие ошибки. Дальше пользователь их исправляет и отправляет форму заново. Этот процесс может повторяться много раз перед тем, как пользователь сделает все правильно.

Технически Django ведет себя так:

  1. Пользователь ввел что-то некорректно — происходит редирект на страницу с формой
  2. Django автоматически записывает данные формы в сессию, а затем использует эти данные для подстановки в форму. Тут участвует ModelForm

Форма

Для реализации добавления новой сущности, нам нужно добавить четыре составляющие: описание формы, маршрут, обработчик маршрута, шаблон:

Форма

Форма описывает поля существующей модели Article. Поэтому для описания формы воспользуемся вспомогательным классом ModelForm, чтобы создать Form-класс из модели Django:

from django.forms import ModelForm
from .models import Article

class ArticleForm(ModelForm):
    class Meta:
        model = Article
        fields = ['name', 'body']

Маршрут

from django.urls import path

from hexlet_django_blog.article.views import IndexView, ArticleFormCreateView

urlpatterns = [
    # ...
    path('create/', ArticleFormCreateView.as_view(), name='articles_create'),
]

Обработчик

В данном get-обработчике мы создаем объект формы и передаем его в шаблон:

class ArticleFormCreateView(View):

    def get(self, request, *args, **kwargs):
        form = ArticleForm()
        return render(request, 'articles/create.html', {'form': form})

Шаблон

<form action="{% url 'articles_create' %}" method="post">
    {% csrf_token %}
    <table border="1">
    {{ form }}
    </table>
    <input type="submit" value="Создать">
</form>

Обработчик данных формы

class ArticleFormCreateView(View):

    def get(self, request, *args, **kwargs):
    # ...

    def post(self, request, *args, **kwargs):
        form = ArticleForm(request.POST)
        if form.is_valid(): # Если данные корректные, то сохраняем данные формы
            form.save()
            return redirect('articles') # Редирект на указанный маршрут
        # Если данные некорректные, то возвращаем человека обратно на страницу с заполненной формой
        return render(request, 'articles/create.html', {'form': form})

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

Первым делом объект request используется в валидации. Валидация в Django привязана к запросу. Она выполняется с помощью метода is_valid(), который доступен в каждом классе формы.

Метод is_valid() возвращает true, если данные формы в порядке, и false — в случае ошибок. Если найдены ошибки, то Django сохраняет данные формы и создает словарь ошибок, который можно получить через поле errors. Самый простой способ вывести ошибки, добавить над формой такой код:

{% if form.errors %}
<div>
    <ul>
    {% for error in form.errors %}
        <li><strong>{{ error|escape }}</strong></li>
    {% endfor %}
    </ul>
</div>
{% endif %}

Вернемся к обработчику. Сразу после валидации данные формы сохраняются:

if form.is_valid():
    form.save()

Когда объект сохранился в базе данных, осталось перенаправить пользователя в нужное место после успешного создания. Обычно отправка идет на список сущностей или страницу редактирования:

return redirect('articles')

Самостоятельная работа

  1. Выполните все шаги из теории
  2. Создайте через интерфейс несколько статей. Проверьте работу валидации
  3. Попробуйте самостоятельно добавить вывод флеш-сообщений

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

  1. Валидатор
  2. Flash-сообщения

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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