如何使用选择的pk在ManyToMany关系中使用prefetch_related

时间:2019-05-19 22:37:55

标签: python django django-queryset python-3.6 django-class-based-views

如何根据“列表”页面上选择的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'

任何帮助将不胜感激。

1 个答案:

答案 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将用作对象的来源;   否则,将使用querysetget_queryset()寻找一个   视图参数中的get_object()参数;如果这个说法   找到后,此方法使用以下方法执行基于主键的查找   值。如果找不到此参数,它将寻找一个   pk_url_kwarg参数,并使用   slug_url_kwarg

     

slug_fieldquery_pk_and_slug时,True将执行   使用主键和子弹进行查找。

然而,名称get_object()有点“误导”,因为人们可能希望它处理一个名称(movie_name ing),而这是一个str对象。也许最好将Movie设置为context_object_name

请注意,尽管'movie'仍需要额外的查询才能将相关类别提取到内存中。因此,在视图中使用.prefetch_related将导致相同数量的查询。

例如,在模板中,您可以使用以下类别渲染movie.categories

movie