Вы можете изменить queryset
вашего DetailView
на:
class MovieDetailView(DetailView):
model = Movie
queryset = Movie.objects<b>.prefetch_related('categories')</b>
template_name = 'snippets/detail.html'
<b>context_object_name = 'movie_name'</b>
Здесь вам не нужно ни выполнять фильтрацию, ни устанавливать get_context_data
. Вы можете указать имя объекта с атрибутом context_object_name
, и DetailView
[Django-doc] автоматически отфильтрует первичный ключ, если URL содержит * Параметр 1013 * (а также для slug
, указанный в URL-адресе, содержит параметр slug
). Документация по get_object
[Django-doc] гласит:
Возвращает один объект, который будет отображаться в этом представлении. Если queryset
при условии, что queryset
будет использоваться в качестве источника объектов;
в противном случае будет использоваться get_queryset()
. get_object()
ищет
pk_url_kwarg
аргумент в аргументах к представлению; если этот аргумент
Этот метод выполняет поиск на основе первичного ключа, используя
значение . Если этот аргумент не найден, он ищет
slug_url_kwarg
и выполняет поиск слагов, используя
slug_field
.
Когда query_pk_and_slug
равен True
, get_object()
выполнит его
поиск с использованием как первичного ключа, так и пули.
Имя movie_name
, однако, немного «вводит в заблуждение», так как можно ожидать, что оно имеет дело с именем (str
ing), тогда как это объект Movie
. Возможно, лучше вместо context_object_name
установить 'movie'
.
Обратите внимание, что .prefetch_related
все равно потребует дополнительного запроса для извлечения связанных категорий в память. Таким образом, использование movie.categories
в представлении приведет к тому же количеству запросов.
В шаблоне, например, вы можете отобразить movie
с такими категориями, как:
{{ movie }}; categories:
{% for category in movie.categories.all %}
{{ category }}
{% endfor %}