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=[] ) )
关键逻辑说明
- 关联链梳理:从
Object1出发,通过sub_object关联到SubObject1,再通过SubObject2的多对多关联到SubObject3,最终关联到用户的sub_object_relation记录。 - Filter条件:
- 第一个条件限定用户存在
ADMIN角色的SubObject3记录; - 第二个条件通过
F('sub_object')绑定当前Object1实例的关联对象,确保SubObject3的关联链指向当前Object1对应的SubObject1。
- 第一个条件限定用户存在
- 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
相关产品推荐
相关产品推荐

