我有书模型和评级模型,
class Book(models.Model):
title = models.CharField(max_length=255)
slug = AutoSlugField(unique=True, populate_from='title')
description = models.TextField()
# more fields
class Rating(models.Model):
book = models.ForeignKey('library.Book')
score = models.DecimalField(max_digits=2, decimal_places=1)
查询,
books = {'books': Book.objects.filter(pk__in=Rating.objects.all().order_by('-score'
).values_list('book__id', flat=True))[:10] }
模板,
{% for i in books %}
{{ i.title }}, {{ i.rating_set.all.first.score }} <br/>
{% endfor %}
将模型呈现给模板,但是django调试工具栏显示为重复n次,其中n是列表中的对象数。当我使用queryset缓存时,它是正常的。
后面发生了什么,我该如何解决这个问题?
感谢。
答案 0 :(得分:8)
没有测试,但你绝对应该预取rating_set
,以便不为每本书创建额外的数据库命中以找到他们的最高分:
rated_books = Rating.objects.all().order_by('-score').values_list('book', flat=True)
books = Book.objects.prefetch_related('rating_set').filter(pk__in=rated_books)[:10]
在模板中,我还怀疑.first
和.all
因为它们可能会导致额外的数据库命中。此外,您无需致电.first
,因为我们已经知道这些评级的图书至少有一个评级对象。
{% for book in books %}
{{ book.title }}, {{ book.rating_set.all.0.score }} <br/>
{% endfor %}
更新:您需要使用rating_set.all.0
代替rating_set.0
来选择优惠费率
答案 1 :(得分:5)
了解select_related和prefetch_related。
Book.objects.filter(pk__in=Rating.objects.all().order_by('-score').values_list('book__id', flat=True)).preferch_related('rating_set')[:10]
在模板中您想要访问图书评分{{ i.rating_set.all.0.score }}
。如果每行中没有select_related
/ prefetch_related
Django,则进行新查询。使用prefetch_related
Django进行了1次查询并获取所有评级。
在您的情况下,问题可能出在.first.
。