Метод get_object
Метод get_object класса DetailView отвечает за извлечение объекта модели, который будет отображаться на странице. Он автоматически использует параметры из URL-адреса, определённые в маршрутизации. По умолчанию метод получает значение параметра 'pk' или 'slug' для идентификации записи. Метод можно переопределить в дочернем классе для добавления кастомной логики поиска, например, фильтрации по полю пользователя или обработки исключений.
Синтаксис
class MyDetailView(DetailView):
model = MyModel
def get_object(self, queryset=None):
# Переопределение метода для кастомного получения объекта
return super().get_object(queryset)
Пример . С использованием pk
Допустим, у нас есть модель 'Article' и мы хотим вывести статью по её идентификатору. Для этого в классе представления указываем модель, а метод get_object автоматически извлечёт объект по переданному параметру 'pk' из URL:
# urls.py
from django.urls import path
from .views import ArticleDetailView
urlpatterns = [
path('article/<int:pk>/', ArticleDetailView.as_view(), name='article-detail'),
]
# views.py
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'
Результат выполнения кода при переходе по URL '/article/1/':
"Object of type Article with pk=1 is retrieved"
Пример . С использованием slug
Если в URL вместо числового идентификатора используется текстовый идентификатор (слаг), то необходимо указать поле 'slug_field'. Метод get_object автоматически выполнит поиск по этому полю:
# urls.py
from django.urls import path
from .views import ArticleSlugDetailView
urlpatterns = [
path('article/<slug:slug>/', ArticleSlugDetailView.as_view(), name='article-slug-detail'),
]
# views.py
from django.views.generic import DetailView
from myapp.models import Article
class ArticleSlugDetailView(DetailView):
model = Article
slug_field = 'slug'
slug_url_kwarg = 'slug'
template_name = 'article_detail.html'
context_object_name = 'article'
Результат выполнения кода при переходе по URL '/article/my-first-article/':
"Object of type Article with slug='my-first-article' is retrieved"
Переопределение метода get_object
Переопределение метода get_object позволяет добавить дополнительную логику, например, фильтрацию по текущему пользователю или обработку ошибок. В этом примере мы возвращаем статью только если она опубликована и принадлежит текущему пользователю:
# views.py
from django.views.generic import DetailView
from django.http import Http404
from myapp.models import Article
class CustomArticleDetailView(DetailView):
model = Article
template_name = 'article_detail.html'
context_object_name = 'article'
def get_object(self, queryset=None):
# Получаем объект стандартным способом
obj = super().get_object(queryset)
# Дополнительные проверки
if obj.status != 'published' or obj.author != self.request.user:
raise Http404("Статья недоступна")
return obj
Результат выполнения кода для авторизованного пользователя, который является автором статьи:
"Article object with custom filtering applied"
Использование queryset в get_object
Метод get_object может принимать аргумент 'queryset', который позволяет задать кастомный набор записей для поиска. Это полезно, если необходимо применить предварительную фильтрацию или оптимизацию запросов:
# views.py
from django.views.generic import DetailView
from myapp.models import Article
class QuerysetArticleDetailView(DetailView):
model = Article
template_name = 'article_detail.html'
context_object_name = 'article'
def get_queryset(self):
# Базовый набор записей с оптимизацией
return Article.objects.select_related('author').filter(status='published')
def get_object(self, queryset=None):
# Используем переданный queryset или получаем его через метод
if queryset is None:
queryset = self.get_queryset()
# Получаем идентификатор из URL
pk = self.kwargs.get('pk')
if pk is not None:
return queryset.get(pk=pk)
# Альтернативно по slug
slug = self.kwargs.get('slug')
if slug is not None:
return queryset.get(slug=slug)
raise Http404("Не удалось найти объект")
Результат выполнения кода при запросе с параметром 'pk=5':
"Article object with author data prefetched"
Смотрите также
-
класс
DetailView,
который использует методget_objectдля отображения деталей объекта -
функция
get_object_or_404,
которая извлекает объект или возвращает ошибку404 -
класс
ListView,
который выводит список объектов, в отличие от детального просмотра -
функция
get_list_or_404,
которая возвращает список объектов или страницу404