Ответ
Метод `get_context_data` в классовых представлениях (Class-Based Views, CBV) Django отвечает за создание и наполнение словаря с контекстом, который передается в шаблон для рендеринга.
Его основная задача — позволить разработчику **добавить в контекст дополнительные, кастомные данные**, которые не предоставляются базовым классом представления по умолчанию.
### Процесс работы
1. Django вызывает метод `get_context_data` во время обработки запроса.
2. Внутри метода **обязательно** нужно сначала вызвать родительскую реализацию через `super().get_context_data(**kwargs)`, чтобы получить базовый контекст (например, `object_list` в `ListView`).
3. Затем в полученный словарь `context` добавляются новые ключи и значения.
4. Модифицированный словарь возвращается из метода.
### Практический пример с `ListView`
```python
# views.py
from django.views.generic import ListView
from .models import Article
class ArticleListView(ListView):
model = Article
template_name = 'articles/article_list.html'
context_object_name = 'articles' # Имя переменной в шаблоне
def get_context_data(self, **kwargs):
# 1. Получаем базовый контекст от родительского класса
context = super().get_context_data(**kwargs)
# 2. Добавляем свои данные
context['total_articles'] = Article.objects.count()
context['page_title'] = 'Список всех статей'
# 3. Возвращаем обновленный контекст
return context
```
### Использование в шаблоне
Теперь в шаблоне `articles/article_list.html` доступны добавленные переменные:
```html
{{ page_title }} (Всего: {{ total_articles }})
-
{% for article in articles %}
- {{ article.title }} {% endfor %}
Ответ 18+ 🔞
А, ну это же про тот самый `get_context_data` в джанговских вьюхах на классах! Слушай, давай разжую, как это работает, а то иной раз смотришь на этот метод и думаешь: «Чё за хуйня, зачем он тут?»
Представь себе, блядь, что твоё представление — это такой заботливый, но слегка туповатый робот-официант. По умолчанию он приносит тебе только основное блюдо — список объектов, или один объект, или форму. И всё, пиздец, на этом его фантазия заканчивается. А тебе-то в шаблон надо передать ещё и салатик, и соус, и, ёпта, может, даже рюмочку какую! Вот `get_context_data` — это как раз твой шанс этому роботу на ушко прошептать: «Слышь, мудила, кроме основного, захвати ещё вот этого и вот этого».
**Как он работает, этот механизм, блядь:**
1. Джанго, обрабатывая запрос, доходит до момента рендеринга шаблона и такой: «Ага, надо контекст собрать». И лезет в твой метод `get_context_data`.
2. Первое и главное правило, которое нарушают все распиздяи, — **НАДО ВЫЗВАТЬ РОДИТЕЛЯ**. `super().get_context_data(**kwargs)`. Это как сказать: «Робот, дай сперва то, что ты обычно даёшь». Иначе останешься без базового контекста, и в шаблоне нихуя не будет работать.
3. Получил ты этот базовый словарь `context`. Теперь туда можно впендюрить что угодно. Добавил ключ — добавил переменную в шаблон. Всё просто, как три копейки.
4. Возвращаешь этот обновлённый словарь обратно, и Джанго с довольной рожой несёт его в шаблон.
**Вот тебе живой пример, смотри, не хулигань:**
```python
# views.py — тут наша кухня
from django.views.generic import ListView
from .models import Article
class ArticleListView(ListView):
model = Article
template_name = 'articles/article_list.html'
context_object_name = 'articles' # Переименовали, чтобы в шаблоне не `object_list`, а по-человечески
def get_context_data(self, **kwargs):
# ШАГ 1: Сука, вызываем родителя! Без этого — пиздец и пустой шаблон.
context = super().get_context_data(**kwargs)
# ШАГ 2: Теперь наша магия. Добавляем что душе угодно.
context['total_articles'] = Article.objects.count() # Считаем все статьи, ебать!
context['page_title'] = 'Список всех статей' # Просто текст, почему бы и нет?
context['current_year'] = 2023 # Да хоть год текущий впендюрь!
# ШАГ 3: Возвращаем этот жирный, набитый данными словарь.
return context
```
**А в шаблоне теперь — раздолье, блядь!**
```html
{{ page_title }} (Всего записей: {{ total_articles }})
Пишем уже который год: {{ current_year }}. Летим в пизду.
-
{% for article in articles %}
- {{ article.title }} {% endfor %}