You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将含array_agg的关联查询SQL转换为Django Queryset?

用Django QuerySet实现等价SQL查询

前提假设

先假设你的Django模型定义如下(对应SQL中的表和字段):

from django.db import models
from django.contrib.postgres.aggregates import ArrayAgg

class S2Followers(models.Model):
    id_s2_users = models.IntegerField()
    id_s2_users1 = models.IntegerField()
    id_s2_user_status = models.IntegerField()

    class Meta:
        db_table = 's2_followers'

class S2Post(models.Model):
    id = models.IntegerField(primary_key=True)
    id_s2_users = models.IntegerField()
    id_s2_post_status = models.IntegerField()

    class Meta:
        db_table = 's2_post'

QuerySet实现代码

queryset = S2Followers.objects.filter(
    id_s2_user_status=1,
    s2post__id_s2_post_status=1  # 过滤关联的Post状态,对应SQL中WHERE的sp.id_s2_post_status=1
).values(
    'id_s2_users'  # 指定分组字段,对应SQL的GROUP BY sf.id_s2_users
).annotate(
    post_ids=ArrayAgg('s2post__id')  # 聚合关联Post的id,对应SQL的array_agg(sp.id)
)

关键说明

  • 过滤逻辑:filter中的id_s2_user_status=1直接对应SQL里的sf.id_s2_user_status=1;s2post__id_s2_post_status=1利用Django的反向关联规则(默认以模型名小写加_set,这里简化为s2post__)过滤关联数据,等价SQL中对sp表的状态过滤。
  • 分组设置:values('id_s2_users')会让QuerySet按该字段分组,完全对应SQL的GROUP BY sf.id_s2_users。
  • 聚合函数:ArrayAgg是Django针对PostgreSQL提供的内置聚合函数,直接匹配SQL的array_agg,需要从django.contrib.postgres.aggregates导入。如果使用其他数据库(如MySQL),需替换为对应函数(比如GroupConcat)。

优化建议(可选)

如果给模型添加显式外键关联,代码会更简洁易读:

class S2Post(models.Model):
    # ...其他字段
    follower = models.ForeignKey(
        S2Followers, 
        on_delete=models.CASCADE, 
        db_column='id_s2_users', 
        related_name='posts'
    )

此时QuerySet可调整为:

queryset = S2Followers.objects.filter(
    id_s2_user_status=1,
    posts__id_s2_post_status=1
).values('id_s2_users').annotate(post_ids=ArrayAgg('posts__id'))

内容的提问来源于stack exchange,提问作者Mahendra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:21:02