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 і зрозумілості коду.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ