В этом посте рассматривается пятая часть серии по классовым представлениям Django (CBV), где мы обсудим, как легко реализовать CRUD с помощью CreateView, UpdateView, DeleteView. В сочетании с ранее обсужденными ListView и DetailView, мы сможем быстро создать полное CRUD-приложение, которое позволяет не только просматривать данные, но и создавать (Create), изменять (Update), удалять (Delete).

Тем, кто еще не читал предыдущие посты о ListView и DetailView, я рекомендую сначала ознакомиться с ними.

Серия по исследованию классовых представлений (CBV) ④ - Использование ListView & DetailView


“Завершите CRUD с помощью обобщенных представлений Django и максимизируйте свою продуктивность!”

В предыдущих постах мы сосредоточились на основной структуре CBV и операциях Чтения (READ) через ListView и DetailView.
В этом тексте мы изучим удобные CreateView, UpdateView, DeleteView, предоставляемые Django, чтобы создать веб-приложение с систематической функцией Создания (Create), Изменения (Update) и Удаления (Delete).


1. CreateView – Создание данных

1.1 Основные концепции и структура

CreateView - это класс из набора представлений Django, который специально предназначен для "создания новых объектов".

  • Автоматизация обработки форм: используя функциональность FormView, внутри метода form_valid() новый объект сохраняется, и после успешного завершения происходит перенаправление на указанный URL.

  • Хорошо работает с ModelForm: указав свойства model и fields или form_class, форма автоматически создается и обрабатывается.

# views.py
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
from .models import Post

class PostCreateView(CreateView):
    model = Post
    fields = ['title', 'content']  # или form_class = PostForm
    template_name = 'post_form.html'
    success_url = reverse_lazy('post_list')  # URL для перенаправления после успешного создания

1.2 Пример подключения в urls.py

# urls.py
from django.urls import path
from .views import PostCreateView

urlpatterns = [
    path('posts/create/', PostCreateView.as_view(), name='post_create'),
]

1.3 Пример шаблона: post_form.html

<!DOCTYPE html>
<html>
<head>
    <title>Создание новой записи</title>
</head>
<body>
    <h1>Создание нового поста</h1>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Сохранить</button>
    </form>
</body>
</html>

Совет: если использовать form_class вместо fields, вы сможете точнее контролировать форму, определяя ModelForm в forms.py.


2. UpdateView – Изменение данных

2.1 Основные концепции и структура

UpdateView - это класс представления, специализирующийся на поиске и изменении существующих объектов.

  • Автоматически извлекает объект, используя значение pk или slug из URL.

  • Форма рендерится с автоматическим заполнением существующими данными, и когда пользователь вносит изменения и отправляет форму, изменения сохраняются в БД.

# views.py
from django.views.generic.edit import UpdateView
from django.urls import reverse_lazy
from .models import Post

class PostUpdateView(UpdateView):
    model = Post
    fields = ['title', 'content']
    template_name = 'post_form.html'
    success_url = reverse_lazy('post_list')  # URL для перенаправления после успешного изменения

2.2 Пример подключения в urls.py

# urls.py
from .views import PostUpdateView

urlpatterns = [
    path('posts/<int:pk>/edit/', PostUpdateView.as_view(), name='post_update'),
]

2.3 Пример шаблона (повторное использование)

Шаблон post_form.html также можно использовать для UpdateView.
В UpdateView form.instance уже представляет собой объект, сохраненный в БД, поэтому существующие данные автоматически заполняются в форму.


3. DeleteView – Удаление данных

3.1 Основные концепции и структура

DeleteView - это класс представления, который используется для поиска и удаления определенного объекта.

  • Когда пользователь отправляет форму подтверждения удаления, соответствующий объект удаляется из БД и происходит перенаправление на указанный URL.

  • Рекомендуется создать один шаблон для “подтверждения удаления” для повышения безопасности.

# views.py
from django.views.generic.edit import DeleteView
from django.urls import reverse_lazy
from .models import Post

class PostDeleteView(DeleteView):
    model = Post
    template_name = 'post_confirm_delete.html'
    success_url = reverse_lazy('post_list')

3.2 Пример подключения в urls.py

# urls.py
from .views import PostDeleteView

urlpatterns = [
    path('posts/<int:pk>/delete/', PostDeleteView.as_view(), name='post_delete'),
]

3.3 Пример шаблона: post_confirm_delete.html

<!DOCTYPE html>
<html>
<head>
    <title>Удаление записи</title>
</head>
<body>
    <h1>Удаление записи</h1>
    <p>Вы действительно хотите удалить этот пост?</p>
    <form method="post">
        {% csrf_token %}
        <button type="submit">Удалить</button>
        <a href="{% url 'post_list' %}">Отмена</a>
    </form>
</body>
</html>

Примечание: DeleteView разработан так, чтобы предотвратить случайное удаление пользователями, вводя процесс "подтверждения удаления".
Если вы хотите удалить объект немедленно, вам нужно реализовать это другим способом (например, с помощью FormView или написанием собственной логики).


4. Обзор процесса завершения CRUD

Концепция CRUD – 4 действия, 5 представлений

4.1 Пример модели: Post

# models.py
class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    def __str__(self):
        return self.title

4.2 urlpatterns (сокращенная версия)

urlpatterns = [
    # 1) ЧТЕНИЕ
    path('posts/', PostListView.as_view(), name='post_list'),                   # Список (ListView)
    path('posts/<int:pk>/', PostDetailView.as_view(), name='post_detail'),      # Подробно (DetailView)

    # 2) СОЗДАНИЕ
    path('posts/create/', PostCreateView.as_view(), name='post_create'),

    # 3) ИЗМЕНЕНИЕ
    path('posts/<int:pk>/edit/', PostUpdateView.as_view(), name='post_update'),

    # 4) УДАЛЕНИЕ
    path('posts/<int:pk>/delete/', PostDeleteView.as_view(), name='post_delete'),
]

4.3 Рекомендуемая структура папок и файлов шаблонов

  • templates/

    • post_list.html

    • post_detail.html

    • post_form.html (Общее для CreateView и UpdateView)

    • post_confirm_delete.html (DeleteView)


5. Как настроить Create/Update/DeleteView

5.1 Управление формой с помощью form_class

class PostCreateView(CreateView):
    model = Post
    form_class = PostForm  # Указание ModelForm
    ...

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

5.2 Динамическое перенаправление с помощью get_success_url()

def get_success_url(self):
    # Например: перейти на страницу деталей используя pk недавно созданного Post
    return reverse_lazy('post_detail', kwargs={'pk': self.object.pk})

self.object ссылается на текущий экземпляр модели, обрабатываемый в Create/Update.

5.3 Контроль доступа, добавление Mixin

  • С помощью LoginRequiredMixin можно сделать так, чтобы “только вошедшие пользователи могли создавать/изменять/удалять”.

  • Если хотите более подробное управление правами доступа, рассмотрите PermissionRequiredMixin или UserPassesTestMixin.


6. Сравнение с FBV

Функция FBV (функциональное представление) Create/Update/DeleteView (классовое представление)
Создание (Create) request.method == 'POST' условие, определение ModelForm напрямую, написание логики сохранения CreateView: Наследование позволяет автоматически обрабатывать создание формы → сохранение → перенаправление
Изменение (Update) Поиск существующего объекта, вставка в форму, повторная проверка и сохранение при POST UpdateView: загрузка существующего объекта → изменение → сохранение, автоматизация логики
Удаление (Delete) GET → рендеринг страницы подтверждения удаления, POST → обработка удаления, перенаправление и т. д. вся логика перемешана в функции DeleteView: извлечение объекта для удаления, все внутренние логики предусмотрены
Читаемость / Поддержка Много условий логики может увеличить длину кода, дублирования одинаковой логики в нескольких местах Переопределение методов позволяет переопределять только необходимые части, минимизируя дублирование
Производительность разработки (ключевые слова) “Много ручной работы, временные затраты, дублирование кода” “Увеличение скорости разработки (экономия времени) и улучшение поддержки (рост продуктивности)”

FBV vs CBV – метафора сборки мебели


7. Заключение: быстро и аккуратно реализуем CRUD с помощью обобщенных представлений!

Используя CreateView, UpdateView, DeleteView, вы можете максимально просто и интуитивно реализовать предварительные операции CRUD в Django.
В частности, логика обработки форм, перенаправление после сохранения данных и другие шаблоны автоматически обрабатываются, позволяя разработчику сосредоточиться на “деловом логике” и “UI/UX”.

Теперь, если вы понимаете ListView + DetailView + CreateView + UpdateView + DeleteView, вы можете легко собрать базовое CRUD-приложение в Django!

В следующем посте мы обсудим TemplateView & RedirectView, чтобы рассмотреть, как аккуратно и автоматически обрабатывать рендеринг простых страниц и перенаправления.


Посмотрите предыдущие посты

  1. Серия по исследованию классовых представлений (CBV) #1 – Причины перехода от FBV к CBV и подход разработчика

  2. Серия по исследованию классовых представлений (CBV) #2 – Понимание базового класса представления Django

  3. Серия по исследованию классовых представлений (CBV) #3 – Упрощение обработки формы с FormView

  4. Серия по исследованию классовых представлений (CBV) #4 – Использование ListView & DetailView


“Используйте обобщенные представления Django для автоматизации реализации CRUD и одновременно повышайте скорость разработки и качество кода!”