2015-11-02 58 views
1

我有一个在Django开发的基于Web的聊天应用程序。人们可以在其中组成自己的聊天小组,邀请他人并在所述小组中喋喋不休。复杂的Django查询集过滤,涉及Q对象和棘手的逻辑

我想孤立谁是最近在网上及所有用户:已发送给定组邀请,或(ii)已经参加(I)(即回复)至少一次同一给定组。请注意,user是香草django.contrib.authuser

要做到这一点,我写:

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) 

注:随时要求获得更多信息;我知道我可能已经遗漏了一些事实。

回答

2

对于已被邀请参加组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())) 

会给出错误“关键字ARG后非关键字ARG”。

您可以通过关键字参数之前,无论是中移动非关键字参数解决这个问题,

User.objects.filter((Q()|Q()), id__in=recently_online) 

或者把它们放在不同的过滤器:

User.objects.filter(id__in=recently_online).filter(Q()|Q()) 

最后,请注意您可能需要在您的查询集上使用distinct(),否则用户可能会出现两次。

+0

感谢您的精心解答,Alasdair。我根据你的建议构建的最终查询是(还没有清理相关名称):User.objects.filter(id__in = user_ids,(Q(invitee__which_group_id = group_id)| Q(reply__which_group_id = group_id)))。distinct ('user')'这给了我一个关键字arg'错误后的非关键字arg,这是我以前从未见过的。那可能是什么? * P.S。我将which_group引用更改为which_group_id,因为我已经很容易在周围了* –

+0

通过参考Q对象的复杂查询文档来解决排序问题:https://docs.djangoproject.com/en/1.8/topics/ db/queries/ –

+1

很高兴你解决了它。我已经更新了答案,解释了你必须在任何关键字参数(如id_in = recent_online)之前放置非关键字'Q()'参数。 – Alasdair