复杂的 Django 查询集过滤,涉及 Q 对象和棘手的逻辑
Complex Django queryset filtering, involving Q objects and tricky logic
我有一个用 Django 开发的基于网络的聊天应用程序。人们可以在里面组建自己的聊天群,邀请其他人在群里聊天。
我想隔离所有最近在线的用户并且:(i) 已经收到给定群组的邀请,或者 (ii) 已经参与(即在同一给定组中至少回复了一次。请注意 user
是香草 django.contrib.auth
user
.
为此,我正在写:
online_invited_replied_users = User.objects.filter(id__in=recently_online,(Q()|Q()))
假设 recently_online
的公式是正确的。这两个Q对象应该是什么?
第一个 Q()
应该参考 invitees
,第二个应该参考至少回复过一次的用户。在此处制定全面、高效的数据库查询时,我似乎 运行 陷入了代码编写者的障碍。请指教!
相关型号为:
class Group(models.Model):
topic = models.TextField(validators=[MaxLengthValidator(200)])
owner = models.ForeignKey(User)
created_at = models.DateTimeField(auto_now_add=True)
class GroupInvite(models.Model):
#this is a group invite object
invitee = models.ForeignKey(User, related_name='invitee')
inviter = models.ForeignKey(User, related_name ='inviter')
sent_at = models.DateTimeField(auto_now_add=True)
which_group = models.ForeignKey(Group)
class Reply(models.Model):
#if a user has replied in a group, count that as participation
text = models.TextField(validators=[MaxLengthValidator(500)])
which_group = models.ForeignKey(Group)
writer = models.ForeignKey(User)
submitted_on = models.DateTimeField(auto_now_add=True)
注意:请随时询问更多信息;我意识到我可能漏掉了一些东西。
对于已经受邀加入组 group
的用户,请向后跟随 GroupInvite.invitee
外键。
already_invited = Q(invitee__which_group=group)
您选择的 related_name invitee
没有任何意义,因为它链接到群组邀请,而不是用户。也许 `group_invites_received' 会更好。
对于已经回复的用户,按照Reply.writer
外键向后。
already_replied = Q(reply__which_group=group)
在本例中为 reply
。因为您没有指定相关名称。
注意你当前的伪代码
User.objects.filter(id__in=recently_online,(Q()|Q()))
会报错'non-keyword arg after keyword arg'.
您可以通过将非关键字参数移到关键字参数之前来解决此问题,
User.objects.filter((Q()|Q()), id__in=recently_online)
或将它们放在单独的过滤器中:
User.objects.filter(id__in=recently_online).filter(Q()|Q())
最后,请注意您可能需要在查询集上使用 distinct()
,否则用户可能会出现两次。
我有一个用 Django 开发的基于网络的聊天应用程序。人们可以在里面组建自己的聊天群,邀请其他人在群里聊天。
我想隔离所有最近在线的用户并且:(i) 已经收到给定群组的邀请,或者 (ii) 已经参与(即在同一给定组中至少回复了一次。请注意 user
是香草 django.contrib.auth
user
.
为此,我正在写:
online_invited_replied_users = User.objects.filter(id__in=recently_online,(Q()|Q()))
假设 recently_online
的公式是正确的。这两个Q对象应该是什么?
第一个 Q()
应该参考 invitees
,第二个应该参考至少回复过一次的用户。在此处制定全面、高效的数据库查询时,我似乎 运行 陷入了代码编写者的障碍。请指教!
相关型号为:
class Group(models.Model):
topic = models.TextField(validators=[MaxLengthValidator(200)])
owner = models.ForeignKey(User)
created_at = models.DateTimeField(auto_now_add=True)
class GroupInvite(models.Model):
#this is a group invite object
invitee = models.ForeignKey(User, related_name='invitee')
inviter = models.ForeignKey(User, related_name ='inviter')
sent_at = models.DateTimeField(auto_now_add=True)
which_group = models.ForeignKey(Group)
class Reply(models.Model):
#if a user has replied in a group, count that as participation
text = models.TextField(validators=[MaxLengthValidator(500)])
which_group = models.ForeignKey(Group)
writer = models.ForeignKey(User)
submitted_on = models.DateTimeField(auto_now_add=True)
注意:请随时询问更多信息;我意识到我可能漏掉了一些东西。
对于已经受邀加入组 group
的用户,请向后跟随 GroupInvite.invitee
外键。
already_invited = Q(invitee__which_group=group)
您选择的 related_name invitee
没有任何意义,因为它链接到群组邀请,而不是用户。也许 `group_invites_received' 会更好。
对于已经回复的用户,按照Reply.writer
外键向后。
already_replied = Q(reply__which_group=group)
在本例中为 reply
。因为您没有指定相关名称。
注意你当前的伪代码
User.objects.filter(id__in=recently_online,(Q()|Q()))
会报错'non-keyword arg after keyword arg'.
您可以通过将非关键字参数移到关键字参数之前来解决此问题,
User.objects.filter((Q()|Q()), id__in=recently_online)
或将它们放在单独的过滤器中:
User.objects.filter(id__in=recently_online).filter(Q()|Q())
最后,请注意您可能需要在查询集上使用 distinct()
,否则用户可能会出现两次。