CBV — это как современные автомобили с автоматической коробкой передач: под капотом происходит много сложных процессов, но вам достаточно знать основные принципы управления, чтобы получить нужный результат.
В этой лекции мы разберем на практических примерах, как использовать Class-Based Views (CBV) в реальном проекте. Если вы читаете эту лекцию, вы уже в курсе, что такое CBV, как их создавать, как они связываются с URL, как использовать TemplateView, ListView, DetailView и другие виды Generic Views. Пора собрать всё воедино.
Проект: Блог с использованием CBV
1. Постановка задачи
Мы создаем упрощенный блог, в котором пользователи могут:
- Просматривать список статей (страница со списком постов).
- Просматривать подробную информацию о конкретной статье.
- Создавать новые статьи.
- Редактировать или удалять уже существующие статьи.
Для этого мы будем использовать следующие CBV:
ListViewдля отображения списка статей.DetailViewдля просмотра деталей статьи.CreateViewдля создания новых постов.UpdateViewиDeleteViewдля их редактирования и удаления.
2. Модели
Создадим модель для хранения данных о статьях. Если вы следовали предыдущим лекциям, создание модели для вас будет знакомым. Вот пример:
# blog/models.py
from django.db import models
from django.urls import reverse
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
def get_absolute_url(self):
# Этот метод используется для редиректа после успешного действия (например, создания поста)
return reverse('post-detail', kwargs={'pk': self.pk})
После создания модели не забудьте выполнить миграции:
python manage.py makemigrations
python manage.py migrate
3. Шаблоны
Для работы нашего блога создадим следующие шаблоны:
post_list.html— для отображения всех постов.post_detail.html— для страницы детали поста.post_form.html— для создания и редактирования постов.post_confirm_delete.html— для подтверждения удаления поста.
Пример post_list.html:
<!-- blog/templates/blog/post_list.html -->
<!DOCTYPE html>
<html>
<head>
<title>Список постов</title>
</head>
<body>
<h1>Список постов</h1>
<ul>
{% for post in object_list %}
<li>
<a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
({{ post.created_at|date:"d M Y" }})
</li>
{% endfor %}
</ul>
<a href="{% url 'post-create' %}">Создать новую статью</a>
</body>
</html>
4. Представления (Views)
Теперь создадим представления для обработки запросов.
Список постов (ListView)
# blog/views.py
from django.views.generic import ListView
from .models import Post
class PostListView(ListView):
model = Post
template_name = 'blog/post_list.html' # По умолчанию: <app>/<model>_list.html
context_object_name = 'posts' # По умолчанию: object_list
ordering = ['-created_at'] # Сортировка: новые посты сверху
Детали поста (DetailView)
# blog/views.py
from django.views.generic import DetailView
class PostDetailView(DetailView):
model = Post
template_name = 'blog/post_detail.html' # По умолчанию: <app>/<model>_detail.html
context_object_name = 'post' # По умолчанию: object
Создание поста (CreateView)
# blog/views.py
from django.views.generic.edit import CreateView
class PostCreateView(CreateView):
model = Post
fields = ['title', 'content'] # Поля, которые нужно отобразить в форме
template_name = 'blog/post_form.html' # По умолчанию: <app>/<model>_form.html
Редактирование поста (UpdateView)
# blog/views.py
from django.views.generic.edit import UpdateView
class PostUpdateView(UpdateView):
model = Post
fields = ['title', 'content']
template_name = 'blog/post_form.html'
Удаление поста (DeleteView)
# blog/views.py
from django.views.generic.edit import DeleteView
from django.urls import reverse_lazy
class PostDeleteView(DeleteView):
model = Post
template_name = 'blog/post_confirm_delete.html'
success_url = reverse_lazy('post-list') # Куда перейти после успешного удаления
5. Маршруты (URLs)
Настроим маршруты для нашего приложения:
# blog/urls.py
from django.urls import path
from .views import (
PostListView,
PostDetailView,
PostCreateView,
PostUpdateView,
PostDeleteView,
)
urlpatterns = [
path('', PostListView.as_view(), name='post-list'), # Список постов
path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'), # Детали поста
path('post/new/', PostCreateView.as_view(), name='post-create'), # Создание поста
path('post/<int:pk>/edit/', PostUpdateView.as_view(), name='post-update'), # Редактирование
path('post/<int:pk>/delete/', PostDeleteView.as_view(), name='post-delete'), # Удаление
]
6. Запуск и тестирование
Теперь можно запустить локальный сервер:
python manage.py runserver
Перейдя на http://127.0.0.1:8000/, вы увидите страницу со списком постов. Попробуйте создать новый пост, отредактировать или удалить его.
7. Советы и типичные ошибки при использовании CBV
Одним из частых вопросов является: "Когда использовать CBV, а когда FBV?" Ответ прост: CBV идеально подходят для стандартных операций (CRUD), но если у вас сложная логика представления — иногда лучше использовать FBV.
Еще одна ошибка — забывать переопределять get_context_data() для передачи контекста. Это важно, особенно если вы добавляете какие-то данные, которые не связаны напрямую с моделью.
8. Расширение проекта
Поздравляю, вы только что реализовали полноценный блог! Конечно, это лишь основа. Можно добавить:
- Авторизацию: чтобы только зарегистрированные пользователи могли создавать или редактировать посты.
- Пагинацию: с использованием встроенных средств
ListView. - Фильтрацию постов: например, по автору или дате.
CBV помогут вам сделать это быстро и удобно, оставаясь верными принципам DRY и понятности кода.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ