Ось твій урок у стилі CS50. Вмикай проектор, поїхали! 🚀
🎓 Тема: Class-Based Views (CBV) — Еволюція твого коду
Привіт, друзі! 👋
Уявіть, що ви працюєте в мерії міста. Ваше завдання — видавати довідки про місце проживання.
Як виглядає ваш день? Приходить людина. Ви берете чистий аркуш паперу. Пишете від руки: "Довідка. Видана такому-то... Адреса така-то... Дата... Підпис..." Приходить наступна. Ви знову берете чистий аркуш. Знову пишете все те саме, змінюючи лише прізвище та вулицю.
До вечора рука відвалюється. 😫
Риторичне питання: Чи не простіше було б мати бланк, де 90% тексту вже надруковано, а вам треба лише вписати ім’я в порожню клітинку?
Власне, у веб-розробці (зокрема в Django): * Function-Based Views (FBV) — це писати все від руки щоразу. * Class-Based Views (CBV) — це той самий бланк.
Сьогодні ми розберемося, як перестати писати один і той самий код знову і знову, і почати жити щасливо.
1. 🔥 Вступ: Проблема «Дня бабака»
Давайте поглянемо на код, який ви, ймовірно, вже писали сотні разів. Уявіть, що ми робимо блог. Нам треба сторінку для відображення списку статей.
Ось типова функція (FBV):
def article_list(request):
# 1. Дістаємо дані з бази
articles = Article.objects.all()
# 2. Готуємо контекст
context = {'articles': articles}
# 3. Рендеримо шаблон
return render(request, 'blog/article_list.html', context)
А тепер уявіть: вам треба зробити список товарів. Список коментарів. Список користувачів. Список замовлень. Ви будете копіювати цей код, змінюючи лише назву моделі та шаблону?
А якщо треба додати пагінацію (сторінки 1, 2, 3...)? Вам доведеться дописувати логіку пагінації у кожну з цих функцій. Це пекло підтримки коду. 🤯
Без CBV не обійтись, коли ваш проєкт переростає стадію "Hello World". Якщо ви хочете масштабуватися і не порушувати принцип DRY (Don't Repeat Yourself) — вам потрібні класи.
2. 🧠 Теоретична база: Що там «під капотом»?
Давайте без академічної нудьги.
Class-Based View (CBV) — це Python-клас, який знає, як обробляти HTTP-запити, тому що він успадковує цю здатність від батьківських класів.
Головна ідея: Спадкування (Inheritance)
Уявіть собі "універсальний автомобіль". У нього є колеса, двигун, кермо. * Якщо вам потрібна вантажівка — ви берете "універсальний автомобіль" і додаєте кузов. * Якщо вам потрібен автобус — ви берете "універсальний автомобіль" і додаєте сидіння.
Вам не треба щоразу винаходити колесо!
У Django (та інших фреймворках) вже написали класи для:
1. Показу простої сторінки (TemplateView).
2. Показу списку (ListView).
3. Показу однієї детальної сторінки (DetailView).
4. Створення/редагування/видалення (CreateView, UpdateView, DeleteView).
⚙️ Механіка: Метод dispatch()
Це — "регулювальник" на перехресті.
Коли запит приходить на CBV, найпершим спрацьовує метод .dispatch(). Він дивиться на запит і каже:
— "Ага, це GET-запит? Тоді я передаю керування методу .get()".
— "Це POST? Тоді йди до методу .post()".
Що треба запам’ятати залізно:
CBV — це не магія. Це просто набір методів, які розбивають обробку запиту на логічні шматки. Ви можете перевизначити (override) будь-який шматок.
3. 🧪 Приклади: Від рутини до елегантності
Приклад 1: Просто показати HTML ("Hello World")
Як було (Function):
def about_page(request):
return render(request, 'about.html')
Як стало (Class):
from django.views.generic import TemplateView
class AboutView(TemplateView):
template_name = "about.html"
Зачекайте, скажете ви. Коду стало навіть більше (на 1 рядок). Навіщо це? Терпіння! Сила класів розкривається, коли стає складніше.
Приклад 2: Список статей (Реальна економія)
Ми хочемо показати список статей із бази даних.
Як це робить CBV ListView:
from django.views.generic import ListView
from .models import Article
class ArticleListView(ListView):
model = Article
template_name = "blog/article_list.html"
context_object_name = "articles" # Як ми назвемо змінну в HTML
Що тут відбулося?
Ми не писали запит Article.objects.all().
Ми не писали return render(...).
Клас ListView зробив це за нас. Ми просто налаштували його: "Візьми модель Article, поклади в шаблон такий-то".
Це декларативний стиль: ми кажемо ЩО ми хочемо, а не ЯК це робити.
Приклад 3: Створення статті (Форми без болю)
Пам'ятаєте обробку форм у функціях?
if request.method == 'POST': form = ... if form.is_valid(): ... save() ... else: form = ...
Жах, правда?
Дивіться сюди:
from django.views.generic import CreateView
from .models import Article
class ArticleCreateView(CreateView):
model = Article
fields = ['title', 'content', 'author'] # Які поля показати
template_name = "blog/article_form.html"
success_url = "/blog/" # Куди перенаправити після успіху
Все! Цей клас сам: 1. Створить форму. 2. Покаже її при GET-запиті. 3. Перевірить валідацію при POST-запиті. 4. Збереже в базу. 5. Зробить редірект.
5 рядків коду замість 15. 😎
4. 🛠 Практична частина
Час "забруднити руки" кодом. У вас є 6 завдань.
🔹 Завдання 1 (Рефакторинг):
У вас є функція contact_us, яка просто рендерить сторінку контактів. Перепишіть її на TemplateView.
🔹 Завдання 2 (Створення списку):
Створіть модель Book (назва, автор). Напишіть BookListView, щоб вивести всі книги.
🔹 Завдання 3 (Ламаємо код):
В BookListView приберіть рядок context_object_name.
Питання: Як тепер звертатися до списку книг у HTML-шаблоні? (Підказка: Django дає стандартне ім'я, спробуйте вгадати або "нагуглити").
🔹 Завдання 4 (Кастомізація):
Вам треба вивести не всі книги, а тільки ті, що написані "Тарасом Шевченком".
Підказка: Вам треба перевизначити метод get_queryset() у вашому класі.
def get_queryset(self):
return Book.objects.filter(...) # допишіть тут
🔹 Завдання 5 (Реальний кейс):
Створіть BookUpdateView. Це клас для редагування існуючої книги. Який URL-параметр йому обов’язково потрібен, щоб знати, яку саме книгу редагувати? (pk або slug).
🔹 Завдання 6 (А що, якщо...):
А що, якщо ми хочемо передати в шаблон не тільки книги, а ще й поточну дату?
Дослідження: Знайдіть метод get_context_data і додайте туди змінну current_date.
5. 💡 Мислення як у розробника
Ви тепер знаєте синтаксис. Але як думає профі?
⚠️ Типова помилка новачка: "CBV для всього"
Новачки іноді намагаються запхати складну, нестандартну логіку в стандартні CBV. Якщо ваша логіка вимагає переписати 80% методів класу — зупиніться. Краще напишіть звичайну функцію (FBV). Класи потрібні для типових задач.
🕵️♂️ Порада сеньйора: Використовуй шпаргалки
Класи в Django мають складну ієрархію. Ніхто (навіть я!) не пам'ятає напам'ять усі атрибути та методи всіх міксинів.
Закладка №1 для вас: ccbv.co.uk (Classy Class-Based Views).
Це "рентген" для класів. Заходите туди, тицяєте на ListView і бачите все, з чого він складається.
🧩 Філософія
Коли ви пишете клас, ви не пишете алгоритм. Ви пишете конфігурацію. "Я хочу сторінку, яка поводиться як список, але бере дані ось звідси і фільтрує їх отак".
6. 🧩 Підсумок
Отже, що ми сьогодні отримали?
- Ми зрозуміли, що FBV — це ручне управління, а CBV — це автопілот.
- Ми навчилися використовувати
ListViewтаCreateView, щоб писати в 3 рази менше коду. - Ми дізналися, що головна сила — у спадкуванні та перевизначенні методів (як
get_queryset).
Тепер ви вмієте: Швидко розгортати стандартні CRUD-інтерфейси (Create, Read, Update, Delete) без копіпасту.
📢 Тизер наступного уроку: Окей, ми створили сторінку редагування статті. Але що, якщо її спробує відредагувати анонімний хакер? 😱 На наступному уроці ми поговоримо про Mixins та Декоратори — як захистити наші Класи і пускати туди тільки "своїх".
А поки що — вперед кодити! Practice makes perfect! 💻