有条件的相关对象的返回值

时间:2018-10-18 13:51:43

标签: django django-orm

例如,我有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中获得用户的参与状态,而在default中如何获得无参与状态?

1 个答案:

答案 0 :(得分:1)

我认为您使事情变得太复杂了,您知道事件的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以多种方式参加活动,则将使用词典最高状态。