Django的SQL查询重复n次

问题描述 投票:10回答:2

我有一本书模型和评级模型,

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是列表中对象的数量。当我使用的查询集缓存,其正常。

enter image description here

怎么回事后面,我怎么能解决这个问题?

谢谢。

python django django-templates django-queryset
2个回答
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 %}

动态:您需要使用qazxsw POI代替qazxsw POI选择第一速度


5
投票

阅读关于rating_set.all.0rating_set.0

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 }} Django的每一行作出新的查询。随着select_related的Django了1个查询并获取所有的评级。

在你的情况下,问题可能出在prefetch_related

© www.soinside.com 2019 - 2024. All rights reserved.