Return 有条件的相关对象的值
Return value of related object with condition
例如我有 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')
我想获取所有用户的信息,还想获取有关与特定事件的关系的信息。如果用户甚至不是参与者 -> 来自参与者模型的 return 状态,否则 -> 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
的参与状态?
我觉得你把事情搞得太复杂了,你知道事件的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
以多种方式参与活动,将使用字典序最高状态。
例如我有 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')
我想获取所有用户的信息,还想获取有关与特定事件的关系的信息。如果用户甚至不是参与者 -> 来自参与者模型的 return 状态,否则 -> 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
的参与状态?
我觉得你把事情搞得太复杂了,你知道事件的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
以多种方式参与活动,将使用字典序最高状态。