Класс DetailView
Класс DetailView применяется для создания страниц просмотра одной записи модели. Он автоматически получает объект по идентификатору из URL-адреса, загружает соответствующий шаблон и передает в него контекстную переменную с объектом. По умолчанию имя этой переменной определяется по имени модели в нижнем регистре. Класс можно настраивать через атрибуты model, template_name, context_object_name и методы get_object, get_context_data.
Синтаксис
from django.views.generic import DetailView
from myapp.models import Article
class ArticleDetailView(DetailView):
model = Article
template_name = 'article_detail.html'
context_object_name = 'article'
Базовый пример
Давайте создадим представление для отображения статьи по её первичному ключу:
# views.py
from django.views.generic import DetailView
from myapp.models import Article
class ArticleDetailView(DetailView):
model = Article
template_name = 'articles/detail.html'
context_object_name = 'article'
В шаблоне 'articles/detail.html' объект будет доступен как 'article':
<h1>{{ article.title }}</h1>
<p>{{ article.content }}</p>
<p>Published: {{ article.created_at }}</p>
Сопоставление URL-адреса с представлением:
# urls.py
from django.urls import path
from myapp.views import ArticleDetailView
urlpatterns = [
path('article/<int:pk>/', ArticleDetailView.as_view(), name='article_detail'),
]
Результат выполнения кода при обращении по адресу '/article/1/':
"Заголовок статьи"
"Содержание статьи"
"Published: 2025-01-15 10:30:00"
Пример . С slug-полем
Давайте настроим представление для использования 'slug' вместо первичного ключа:
# views.py
from django.views.generic import DetailView
from myapp.models import Article
class ArticleDetailView(DetailView):
model = Article
template_name = 'articles/detail.html'
context_object_name = 'article'
slug_field = 'slug'
slug_url_kwarg = 'slug'
Сопоставление URL-адреса с 'slug' в пути:
# urls.py
from django.urls import path
from myapp.views import ArticleDetailView
urlpatterns = [
path('article/<slug:slug>/', ArticleDetailView.as_view(), name='article_detail'),
]
Пример . С переопределением метода get_object
Давайте добавим дополнительную логику для извлечения объекта, например, чтобы получить объект по пользователю и slug-полю:
# views.py
from django.views.generic import DetailView
from django.shortcuts import get_object_or_404
from myapp.models import Article
class ArticleDetailView(DetailView):
model = Article
template_name = 'articles/detail.html'
context_object_name = 'article'
def get_object(self, queryset=None):
slug = self.kwargs.get('slug')
user = self.request.user
return get_object_or_404(Article, slug=slug, author=user)
Пример . С дополнительными данными в контексте
Давайте передадим в шаблон не только объект статьи, но и дополнительные данные, например, количество просмотров:
# views.py
from django.views.generic import DetailView
from myapp.models import Article, ViewCounter
class ArticleDetailView(DetailView):
model = Article
template_name = 'articles/detail.html'
context_object_name = 'article'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
article = self.get_object()
views = ViewCounter.objects.filter(article=article).count()
context['views_count'] = views
return context
В шаблоне теперь доступна переменная 'views_count':
<h1>{{ article.title }}</h1>
<p>{{ article.content }}</p>
<p>Views: {{ views_count }}</p>
Смотрите также
-
класс
ListView,
который отображает список объектов модели -
метод
get_object,
который отвечает за получение объекта в DetailView -
класс
CreateView,
который используется для создания новых объектов -
класс
UpdateView,
который используется для редактирования существующих объектов