【发布时间】:2021-10-25 00:31:21
【问题描述】:
我在 EBS 上有一个 Django 项目,其中一种返回 Article 对象的 QuerySet 的方法需要很长时间。我想对其进行优化,使其只有一两个查询,但我不确定它是否可能。
型号:WebSite,Article
查询是来自不同网站的Articles列表。
WebSite 模型具有home_order 和home_article_count 属性,用于选择文章的数量以及它们的顺序。
网站 A、B 和 C 的示例:
-
A-A.home_order = 2,A.home_article_count=3 -
B-B.home_order = 1,B.home_article_count=5 -
C-C.home_order = 3,C.home_article_count=7
结果将是(aA 表示来自网站 A 的文章):
aB,aB,aB,aB,aB,aA,aA,aA,aC,aC,aC,aC,aC,aC,aC
列表以aB 开头,表示来自网站B 的文章,因为B.home_order=1,有5 篇aB 文章为B.home_article_count=5。
现在,这是一个返回文章的Manager 方法:
def home(self) -> QuerySet:
articles_pks = []
for ws in WebSite.objects.active().order_by('home_order', 'name'):
articles_pks.extend(ws.articles.filter(is_active=True).order_by('-created')[:ws.home_article_count].values_list('pk',flat=True))
return self.get_queryset().filter(pk__in=articles_pks)
这意味着,对于 20 个 WebSite 对象,有 21 个查询(一个获取网站,另一个获取文章 20 个)。
是否可以在尊重WebSite.home_order 和WebSite.home_article_count 的同时将其合并为一个或两个查询?
【问题讨论】:
-
这是 home 的全部代码吗?
return self.get_queryset().filter(pk__in=articles_pks)不关心订单还是您只是删除了一些代码以使其简短? -
@bdbd 这是全部代码,谢谢通知。
-
到目前为止,使用
self.get_queryset().filter(pk__in=articles_pks)取消订购似乎很旧。这是故意的吗? -
@bdbd 不,这不是故意的,但我可以在内存中对其进行排序,这没什么大不了的。
标签: python django postgresql orm django-orm