Класс DetailView

Класс DetailView применяется для создания страниц просмотра одной записи модели. Он автоматически получает объект по идентификатору из URL-адреса, загружает соответствующий шаблон и передает в него контекстную переменную с объектом. По умолчанию имя этой переменной определяется по имени модели в нижнем регистре. Класс можно настраивать через атрибуты model, template_name, context_object_name и методы get_object, get_context_data.

Синтаксис

pythonfrom django.views.generic import DetailView
from myapp.models import Article

class ArticleDetailView(DetailView):
  model = Article
  template_name = 'article_detail.html'
  context_object_name = 'article'

Базовый пример

Давайте создадим представление для отображения статьи по её первичному ключу:

python# 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':

html<h1>{{ article.title }}</h1>
<p>{{ article.content }}</p>
<p>Published: {{ article.created_at }}</p>

Сопоставление URL-адреса с представлением:

python# 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/':

python"Заголовок статьи"
"Содержание статьи"
"Published: 2025-01-15 10:30:00"

Пример . С slug-полем

Давайте настроим представление для использования 'slug' вместо первичного ключа:

python# 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' в пути:

python# 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-полю:

python# 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)

Пример . С дополнительными данными в контексте

Давайте передадим в шаблон не только объект статьи, но и дополнительные данные, например, количество просмотров:

python# 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':

html<h1>{{ article.title }}</h1>
<p>{{ article.content }}</p>
<p>Views: {{ views_count }}</p>

Смотрите также

  • класс ListView,
    который отображает список объектов модели
  • метод get_object,
    который отвечает за получение объекта в DetailView
  • класс CreateView,
    который используется для создания новых объектов
  • класс UpdateView,
    который используется для редактирования существующих объектов