如何根据列表页面上选择的 pk 在详细信息页面中显示电影所属的类别:多对多关系。我正在寻找一种可能的方法来使用 prefetch_lated 来完成此操作。任何其他方式也可以。
模型.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')
View .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] 指定对象的名称。如果 url 包含 pk
参数,则自动过滤主键(如果 url 包含 slug
参数,则自动过滤 slug
) 。 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
有点“误导”,因为人们可能认为它处理的是名称(字符串
ing),而这是一个 电影
对象。也许最好将 context_object_name
设置为 'movie'
。
请注意,.prefetch_lated
仍然需要额外的查询才能将相关类别提取到内存中。因此,在 View 中使用 movie.categories
将导致相同数量的查询。
在模板中,您可以使用以下类别渲染电影
:
{{ movie }}; categories:
{% for category in movie.categories.all %}
{{ category }}
{% endfor %}
关于python - 如何使用 pk selected 在 ManyToMany 关系中使用 prefetch_lated,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56212567/