如何通过Django ORM单查询获取含共享字段的所有关联用户ID
单条Django ORM语句获取所有可访问条款的用户ID
你可以利用Django的Unnest数据库函数展开shared_with数组,再通过union合并user_id和展开后的共享用户ID,实现单条ORM语句完成查询,代码如下:
from django.db.models.functions import Unnest all_accessible_user_ids = ( # 获取所有活跃条款的拥有者ID并去重 Term.objects.filter(active=True) .values_list('user_id', flat=True) .distinct() # 合并展开共享用户ID的查询结果 .union( Term.objects.filter(active=True, shared_with__isnull=False) .annotate(shared_user_id=Unnest('shared_with')) .values_list('shared_user_id', flat=True) .distinct() ) )
逻辑说明:
- 提取条款拥有者ID:通过
filter(active=True)筛选活跃条款,values_list('user_id', flat=True)获取扁平化的用户ID列表,distinct()去重。 - 展开并提取共享用户ID:使用
Unnest('shared_with')将数组字段展开为单个用户ID的多行记录,通过annotate生成临时字段shared_user_id,同样用values_list提取并去重,同时过滤shared_with__isnull=False跳过空数组的无效数据。 - 合并结果:
union方法会自动合并两个查询集并去重,最终得到所有可访问条款的用户ID集合。
注意事项:
Unnest函数从Django 2.0开始支持,且仅适用于PostgreSQL数据库(因为ArrayField是PostgreSQL专属字段)。- 这种方式将所有计算逻辑放在数据库层面完成,相比Python端循环拼接集合,性能更优,同时减少了数据库请求次数。
内容的提问来源于stack exchange,提问作者Leonardo Furtado
相关产品推荐
相关产品推荐

