如何使用 pk selected 在 ManyToMany 关系中使用 prefetch_related
How to use prefetch_related in a ManyToMany relation using pk selected
如何根据在列表页面上选择的 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'
如有任何帮助,我们将不胜感激。
您可以将 DetailView
的 queryset
更改为:
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] will automatically filter on the primary key given the url contains a pk
parameter (as well as on the slug
given the url contains a slug
parameter). The documentation on get_object
[Django-doc] 表示:
Returns the single object that this view will display. If queryset
is provided, that queryset
will be used as the source of objects;
otherwise, get_queryset()
will be used. get_object()
looks for a
pk_url_kwarg
argument in the arguments to the view; if this argument
is found, this method performs a primary-key based lookup using that
value. If this argument is not found, it looks for a
slug_url_kwarg
argument, and performs a slug lookup using the
slug_field
.
When query_pk_and_slug
is True
, get_object()
will perform its
lookup using both the primary key and the slug.
名称 movie_name
然而有点 "misleading" 因为人们可能认为这是处理名称(str
ing),而这是 Movie
目的。也许最好将 context_object_name
设置为 'movie'
。
请注意,.prefetch_related
仍然需要额外的查询才能将相关类别提取到内存中。因此在视图中使用 movie.categories
,将导致相同数量的查询。
在模板中,您可以使用以下类别渲染 movie
:
{{ movie }}; categories:
{% for category in movie.categories.all %}
{{ category }}
{% endfor %}
如何根据在列表页面上选择的 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'
如有任何帮助,我们将不胜感激。
您可以将 DetailView
的 queryset
更改为:
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] will automatically filter on the primary key given the url contains a pk
parameter (as well as on the slug
given the url contains a slug
parameter). The documentation on get_object
[Django-doc] 表示:
Returns the single object that this view will display. If
queryset
is provided, thatqueryset
will be used as the source of objects; otherwise,get_queryset()
will be used.get_object()
looks for apk_url_kwarg
argument in the arguments to the view; if this argument is found, this method performs a primary-key based lookup using that value. If this argument is not found, it looks for aslug_url_kwarg
argument, and performs a slug lookup using theslug_field
.When
query_pk_and_slug
isTrue
,get_object()
will perform its lookup using both the primary key and the slug.
名称 movie_name
然而有点 "misleading" 因为人们可能认为这是处理名称(str
ing),而这是 Movie
目的。也许最好将 context_object_name
设置为 'movie'
。
请注意,.prefetch_related
仍然需要额外的查询才能将相关类别提取到内存中。因此在视图中使用 movie.categories
,将导致相同数量的查询。
在模板中,您可以使用以下类别渲染 movie
:
{{ movie }}; categories:
{% for category in movie.categories.all %}
{{ category }}
{% endfor %}