首页 > 解决方案 > 需要 Django 查询优化(2 个查询而不是 21 个)

问题描述

我在 EBS 上有一个 Django 项目,一个返回Article对象 QuerySet 的方法需要很长时间。我想对其进行优化,使其只是一两个查询,但我不确定它是否可能。

型号:WebSite,Article

查询是Articles来自不同网站的列表。

WebSitemodel 有一个home_orderhome_article_count属性,用于选择许多文章以及它们的顺序。

网站 A、B 和 C 的示例:

  1. A- A.home_order = 2,A.home_article_count=3
  2. B- B.home_order = 1,B.home_article_count=5
  3. 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有 5aB篇文章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是否可以在尊重and的同时将其合并到一个或两个查询中WebSite.home_article_count

标签: pythondjangopostgresqlormdjango-orm

解决方案


尝试使用OR |运算符组合查询集:

def home(self) -> QuerySet:
    articles_pks = Article.objects.none()
    for ws in WebSite.objects.active().order_by('home_order', 'name'):
        articles_pks = articles_pks | ws.articles.filter(is_active=True).order_by('-created')[:ws.home_article_count]
    return self.get_queryset().filter(pk__in=articles_pks.values_list('pk',flat=True)))

您应该只得到两个查询,一个用于获取网站,另一个用于构建和使用文章列表。


推荐阅读