Django аннотирует qs по объектам с помощью поля object_id

Получил пользователя и роль. Как я могу получить аннотированные роли qs по пользователям?

from django.db import models, F, Q

class User(models.Model):
    pass


class Role(models.Model):
    ...
    user_id = models.PositiveIntegerField(
        verbose_name='Related object ID'
    )

Я хочу сделать что-то вроде этого:

roles = Role.objects.all()
roles = roles.annotate(user=Q(User.objects.get(id=F('user_id'))))

for role in roles:
    print(role.user.id) => 123

Traceback:

FieldError: Cannot resolve keyword 'user_id' into field

PS: Мне не нужны ForeignKey или ManytoMany, мне нужно именно это отношение.

Решение, которое вы указали в вопросе, здесь не сработает, потому что запрос F(...) указывает на саму модель User, а не на модель Role. Следовательно, он не может разрешить поле.

Кроме того, я бы рекомендовал то, что @Iain упомянул в разделе комментариев, потому что таким образом вы можете получить прямой доступ к объекту пользователя из объекта Role. Для этого вы можете рассмотреть отношение OneToOne.

С другой стороны, если вы не хотите иметь отношения в моделях, то в лучшем случае вы можете получить доступ к одному из полей из модели User следующим образом (используя subquery):

from django.db.models import OuterRef, Subquery

roles = roles.annotate(username=Subquery(User.objects.filter(id=OuterRef('user_id')).values('username')[:1]))
Вернуться на верх