Возвращаемое значение связанного объекта с условием - PullRequest
0 голосов
/ 18 октября 2018

Как, например, у меня есть 3 модели: Пользователь, Событие, Участник

class Event(..):
    creator = models.ForeignKey('users.User', on_delete=models.CASCADE, related_name='event_creator_set')


class Participator(..):
    status = models.CharField(..)
    event = models.ForeignKey('events.Event', on_delete=models.CASCADE, related_name='participators_set')
    user = models.ForeignKey('users.User', on_delete=models.CASCADE, related_name='participations_set')

Я хочу получить всех пользователей, а также получить информацию о связи с конкретным событием.Если пользователь даже не является участником -> вернуть статус из моделей Участника, иначе -> null Вот мои запросы:

 e = Event.objects.first()
 users = User.objects.annotate(is_participationg=Case(When(id__in=e.participators_set.values_list('user__id', flat=True), then=Value(True)), default=Value(False), output_field=BooleanField()))

Так что я могу знать, участвует ли пользователь в определенном событии.Как я могу получить статус участника в then и None в default?

1 Ответ

0 голосов
/ 18 октября 2018

Я думаю, что вы делаете вещи слишком сложными, вы знаете id события, поэтому вы можете фильтровать как:

from django.db.models import Case, CharField, F, Max, Value, When

User.objects.annotate(
    participation_status=Max(Case(
        When(participations_set__event=e, then=F('participations_set__status')),
        default=Value(None),
        output_field=CharField()
    ))
)

Это приводит к запросу:

SELECT user.*,
       MAX(CASE WHEN participator.event_id = 123
           THEN participator.status
           ELSE NULL END
       ) AS participation_status
FROM user
LEFT OUTER JOIN participator ON (user.id = participator.user_id)
GROUP BY user.id

123 в действительности первичным ключом e).

Если User участвовал в событии несколькими способами, лексикографический максимальный статус будетб.

...