Аннотирование объекта со списком объектов, связанных с ним, но отфильтрованных
У меня есть следующие объекты (упрощенно, только для этого вопроса)
class Object1(models.Model):
users_assigned_to_object1 = models.ManyToMany(Users, related_name='objects')
sub_object = models.ForeignKey(SubObject1)
class Users(models.Model):
first_name = models.CharField(max_length=1000)
class SubObject1(models.Model):
sub_object_name = models.CharField(max_length=1000)
class SubObject2(models.Model):
sub_object_1 = models.ManyToMany(SubObject1)
class SubObject3(models.Model):
sub_object_2 = models.ManyToMany(SubObject3)
role_name = models.CharField(max_length=1000)
user = models.ForeignKey(Users, related_name='sub_object_relation')
По более сложным причинам, которые сейчас не имеют значения, мне нужно иметь возможность аннотировать Object1
с пользователями, которые являются пользователями, назначенными на объект 1, и где эти пользователи имеют role_name=ADMIN
хотя бы для одной из SubObject3
моделей, которые связаны с Object1
.
Например, я пытаюсь получить что-то вроде этого:
Object1.objects.annotate(admin_users=X)
Что происходит на Х?
Я работаю на Django 4.2 и использую БД Postgres
Я пробовал использовать подзапросы, но они не работают со списками (а этот запрос может вернуть список), пробовал делать что-то с помощью условных выражений Django (например, ArrayAgg, When), но так и не смог найти правильное решение в этом вопросе.
Похоже, вы ищете ArraySubquery
.
from django.contrib.postgres.expressions import ArraySubquery
from django.db.models import F, OuterRef
from django.db.models.functions import JSONObject
users = Users.objects.filter(
subobject3__role_name='ADMIN',
subobject3__sub_object_2__sub_object_1=OuterRef('pk')
).annotate(json=JSONObject(id=F('id'), first_name=F('first_name'))
Object1.objects.annotate(admin_users=ArraySubquery(users.values('json'))