2015-11-08 30 views
0

这是一个艰难的。我有一个基于django的网络应用程序,用户可以发布有趣的网址,并在每次发布时让观众留言。此外,我使用stealth banning反对行为不端的用户。制定一个高度具有挑战性的需求的高效DB查询(Django应用程序)

有趣的URL由Link模型表示;帖子下的评论已被Publicreply模型复制。

下面是这些车型是如何与一个其他:

class Link(models.Model): 
    submitter = models.ForeignKey(User) 
    submitted_on = models.DateTimeField(auto_now_add=True) 
    url = models.URLField(max_length=250) 

class Publicreply(models.Model): 
    submitted_by = models.ForeignKey(User) 
    answer_to = models.ForeignKey(Link) 
    submitted_on = models.DateTimeField(auto_now_add=True) 
    description = models.TextField(validators=[MaxLengthValidator(250)]) 

Users我禁止去这里:

class HellBanList(models.Model): 
    condemned = models.ForeignKey(User) 
    when = models.DateTimeField(auto_now_add=True) 

什么是我的问题吗?我试图写表现最好的优化的查询这让我:

的与绝对最新时间戳publicreply从所有不同links无论是用户自己张贴中,OR低于上述用户留下了publicreply

2.但是,如果在1得到的publicreply对象是人谁是的HellBanList部分(即condemne d属性),我想忽略那个特定的publicreply并挖掘下一个最近的一个。如果这也是被禁用的用户,我会跳到下一个(依此类推)。

最后,我只迎合双方1和2


所以以后我有什么企图迄今需要从publicreply对象我结束了submitted_bysubmitted_on属性值?这个:

freshest_link = Link.objects.filter(Q(submitter=self.request.user)|Q(publicreply__submitted_by=self.request.user)).distinct().annotate(date=Max('publicreply__submitted_on')).latest('date') 
freshest_reply = Publicreply.objects.filter(answer_to=freshest_link).latest('submitted_by') 

这段代码有什么问题?它不符合要求的事实。我想我应该有某种方式HellBanList之前运行publicreplys一个exclude()发表users计算freshest_reply(以满足要求)。无论如何,我无法弄清楚如何做到这一点。其次,专家可能会比我尝试创建更有效的整个查询,目标是尽可能少的数据库往返。

你能帮忙吗?如果您在描述我想要达到的目标时觉得自己不透明,请要求澄清。

注:我的数据库是Postgres的

回答

1

获取禁止用户列表,如:

banlist = HellBanList.objects.values_list('condemned',flat=True) 

修改freshest_reply查询,如:

freshest_reply = Publicreply.objects.filter(answer_to=freshest_link).exclude(submitted_by_id__in=banlist).latest('submitted_on') 

第二个方法:

在您的查询中,首先获取Link,它具有最新的公开回复,在下一个查询中,您将获得该Link的最新Publicreply。而不是我们可以在一个查询中得到最新的回复,例如:

latest_reply = Publicreply.objects.filter(Q(answer_to__submitter=self.request.user)|Q(submitted_by=self.request.user)).exclude(submitted_by_id__in=banlist).latest('submitted_on') 

让我知道我是否错过了一些东西。

+0

太棒了,Anush!第二种方法尤其是配置文件很好(我增加了一个exclude() - 用于self.request.user - 但这不在请求中,所以不用担心)。感谢您在哥们里打闹。我还有另一个我还没有测试和接受的答复。不久! –