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

Django 4.2中如何为Object1注解符合条件的关联管理员用户

解决方案

首先修正模型中的笔误:SubObject3类的sub_object_2字段应该关联SubObject2而非自身,否则无法建立有效关联:

class SubObject3(models.Model):
  sub_object_2 = models.ManyToMany(SubObject2)  # 修正此处
  role_name = models.CharField(max_length=1000)
  user = models.ForeignKey(Users, related_name='sub_object_relation')

接下来,使用ArrayAgg结合条件过滤实现需求,X的具体写法如下:

from django.db.models import ArrayAgg, Q, F
from django.contrib.postgres.aggregates import ArrayAgg

# 注解查询
Object1.objects.annotate(
    admin_users=ArrayAgg(
        # 可根据需求替换为用户的其他字段,如first_name、id
        'users_assigned_to_object1__id',
        # 核心过滤条件
        filter=Q(
            users_assigned_to_object1__sub_object_relation__role_name='ADMIN',
            # 关联当前Object1实例对应的SubObject1
            users_assigned_to_object1__sub_object_relation__sub_object_2__sub_object_1=F('sub_object')
        ),
        # 去重避免同一用户因多条SubObject3记录重复出现
        distinct=True,
        # 无符合条件用户时返回空列表
        default=[]
    )
)

关键逻辑说明

  1. 关联链梳理:从Object1出发,通过sub_object关联到SubObject1,再通过SubObject2的多对多关联到SubObject3,最终关联到用户的sub_object_relation记录。
  2. Filter条件:
    • 第一个条件限定用户存在ADMIN角色的SubObject3记录;
    • 第二个条件通过F('sub_object')绑定当前Object1实例的关联对象,确保SubObject3的关联链指向当前Object1对应的SubObject1。
  3. ArrayAgg作用:解决SubQuery只能返回单个值的局限,聚合符合条件的用户字段为数组,满足返回用户列表的需求。

扩展:返回完整用户对象(可选)

若需要返回完整的用户对象而非单个字段,可结合Cast和JSONField(需PostgreSQL支持):

from django.db.models import Cast
from django.db.models.fields import JSONField

Object1.objects.annotate(
    admin_users=ArrayAgg(
        Cast('users_assigned_to_object1', JSONField()),
        filter=Q(
            users_assigned_to_object1__sub_object_relation__role_name='ADMIN',
            users_assigned_to_object1__sub_object_relation__sub_object_2__sub_object_1=F('sub_object')
        ),
        distinct=True,
        default=[]
    )
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 12:27:44