需要 Django 查询优化(2 个查询而不是 21 个)

Need Django Query optimization (2 Queries instead of 21)

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

型号:WebSiteArticle

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

WebSite 模型有一个 home_orderhome_article_count 属性,用于 select 一些文章以及它们的顺序。

网站 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,有 5 aB 篇文章 B.home_article_count=5

现在,这是 returns 文章的 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_orderWebSite.home_article_count 的情况下将其合并为一个或两个查询?

尝试使用 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)))

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