如何根据“列表”页面上选择的pk在详细信息页面中显示电影所属的多对多关系。我正在寻找一种可能的方式来使用prefetch_related实现此目的。任何其他方式都可以。
models.py
class Movie(models.Model):
title = models.CharField(max_length=70)
description = models.TextField(max_length=500)
class Category(models.Model):
name = models.CharField(max_length=70)
movie = models.ManyToManyField(Movie, related_name='categories')
views.py
class MovieListView(ListView):
model = Movie
context_object_name = 'movies'
template_name = 'snippets/index.html'
def get_queryset(self):
return Movie.objects.all()
class MovieDetailView(DetailView):
model = Movie
template_name = 'snippets/detail.html'
任何帮助将不胜感激。
答案 0 :(得分:2)
您可以将queryset
中的DetailView
更改为:
class MovieDetailView(DetailView):
model = Movie
queryset = Movie.objects.prefetch_related('categories')
template_name = 'snippets/detail.html'
context_object_name = 'movie_name'
您无需在此处进行过滤,也无需设置get_context_data
。您可以使用context_object_name
属性指定对象的名称,并且给定的url包含pk
参数(以及{{ 1}}(给出的网址包含一个slug
参数)。 DetailView
[Django-doc]说:
返回此视图将显示的单个对象。如果
slug
提供queryset
将用作对象的来源; 否则,将使用queryset
。get_queryset()
寻找一个 视图参数中的get_object()
参数;如果这个说法 找到后,此方法使用以下方法执行基于主键的查找 值。如果找不到此参数,它将寻找一个pk_url_kwarg
参数,并使用slug_url_kwarg
。当
slug_field
为query_pk_and_slug
时,True
将执行 使用主键和子弹进行查找。
然而,名称get_object()
有点“误导”,因为人们可能希望它处理一个名称(movie_name
ing),而这是一个str
对象。也许最好将Movie
设置为context_object_name
。
请注意,尽管'movie'
仍需要额外的查询才能将相关类别提取到内存中。因此,在视图中使用.prefetch_related
将导致相同数量的查询。
例如,在模板中,您可以使用以下类别渲染movie.categories
:
movie