Django DRF:如何预取我的属性的查询集?
我的模型Django DRF:如何预取我的属性的查询集?,django,django-rest-framework,Django,Django Rest Framework,我的模型Author上有很多属性。他们每个人都使用self.book\u set class Author(models.Model): #.... @property def book_impressions(self): return self.book_set.aggregate(Sum("impressions").get("impressions__sum") or 0 @property
Author
上有很多属性。他们每个人都使用self.book\u set
class Author(models.Model):
#....
@property
def book_impressions(self):
return self.book_set.aggregate(Sum("impressions").get("impressions__sum") or 0
@property
def book_reach(self):
return self.book_set.aggregate(Sum("reach").get("reach__sum") or 0
# more @property here...
class Book(models.Model):
author = models.ForeignKey(Author)
reach = models.IntegerField()
impressions = models.IntegerField()
# ....
我有一个视图负责检索单个
作者
。正如您可能想象的那样,数据库经常受到攻击。插入myprefetch\u related
的正确点在哪里?这不会有帮助,因为聚合将进行额外的查询,即使查询集是预取的,也会在数据库端进行累加。即使您这样预取了相关书籍,Django也会发现您没有迭代.all()
并进行额外的查询
您可以使用的是:
因此,您可能希望完全删除属性,因为这些属性确实会带来N+1问题。这不会有帮助,因为聚合将进行额外的查询,即使查询集是预取的,因为
.aggregates
是在数据库端加总的。您可以使用的是.annotate
@WillemVanOnsem-那么您是否建议将属性的逻辑移动到相应视图的get\u queryset
方法?是的,因为这将大量生成注释。
from django.db.models import Sum, Value
from django.db.models.functions import Coalesce
Author.objects.annotate(
impressions=Coalesce(Sum('book__impressions'), Value(0)),
reach=Coalesce(Sum('book__reach'), Value(0))
)
SELECT author.*,
COALESCE(SUM(book.impressions), 0) AS impresssions,
COALESCE(SUM(book.reach), 0) AS impresssions
FROM author
LEFT OUTER JOIN book ON book.author_id = author.id
GROUP BY author.id