代码之家  ›  专栏  ›  技术社区  ›  Mat

我能用django聚合函数过滤多个对映体吗?

  •  0
  • Mat  · 技术社区  · 17 年前

    如何使用django的聚合功能计算具有多个约束的记录?

    使用django trunk,我试图用django聚合替换复杂的数据库特定SQL语句。举个例子,假设我有一个数据库,其中包含在许多域上运行的博客表(想想看)。英国公司,每个人都有许多评论:

    domains <- blog -> comment
    

    以下SQL按域计算注释数:

    SELECT D.id, COUNT(O.id) as CommentCount FROM domain AS D
    LEFT OUTER JOIN blog AS B ON D.blog_id = B.id
    LEFT OUTER JOIN comment AS C ON B.id = C.blog_id
    GROUP BY D.id
    

    这很容易复制:

    Domain.objects.annotate(Count('blogs__comments'))
    

    更进一步,我希望能够添加一个或多个约束并复制以下SQL:

    SELECT D.id, COUNT(O.id) as CommentCount FROM domain AS D
    LEFT OUTER JOIN blog AS B ON D.blog_id = B.id
    LEFT OUTER JOIN comment AS C ON B.id = C.blog_id
        AND C.active = True
    GROUP BY D.id
    

    这很难复制,因为django似乎包含了一个WHERE子句来过滤整个shabbood:

    Domain.objects.filter(blogs__comments__active=True)
                  .annotate(Count('blogs__comments'))
    

    SQL的结果是这样的:

    SELECT ..., COUNT(comment.id) AS blog__comments__count FROM domain
    LEFT OUTER JOIN blog ON domain.blog_id = blog.id
    LEFT OUTER JOIN comment ON blog.id = comment.blog_id
    WHERE comment.active = True
    GROUP BY domain.id
    ORDER BY NULL
    

    我如何说服django在适当的 LEFT OUTER JOIN ? 这很重要,因为我想包括那些没有评论的博客的计数。

    1 回复  |  直到 17 年前
        1
  •  0
  •   Jason Champion    17 年前

    我不知道如何使用Django查询语言来实现这一点,但是您可以始终运行原始SQL查询。如果您还不知道如何做到这一点,下面是一个例子:

    from django.db import connection
    
    def some_method(request, some_parameter):
        cursor = connection.cursor()
        cursor.execute('SELECT * FROM table WHERE somevar=%s', [some_parameter])
        rows = cursor.fetchall()
    

    更多详情请参见Django在线丛书: http://www.djangobook.com/en/2.0/chapter05/

    查找“在视图中执行数据库查询的愚蠢方法”一节。如果你不想用“愚蠢”的方式,我不知道你的选择是什么。

    推荐文章