2013-05-16 233 views
7

我使用annotate将一个属性添加到一个对象,然后我可以使用它作为order_by。但是,我想在关系的关系字段上注释。我知道我应该能够使用双下划线符号以某种方式到达场地,但我似乎无法将我的头围绕在它周围。Django:如何order_by在相关领域的相关领域

下面是型号:

class Group(Taggable, Uploadable): 
    name   = models.CharField(max_length=250, db_index=True) 
    description  = models.TextField(max_length=5000, null=True, 
         blank=True, db_index=True) 
    private   = models.BooleanField(default=False) 
    members   = models.ManyToManyField(User, null=True, 
         related_name='members', through='GroupToUser') 
    pending_members = models.ManyToManyField(User, null=True, 
         related_name='pending_members') 
    admin   = models.ForeignKey(User, null=True) 
    timestamp  = models.DateTimeField(auto_now_add=True) 
    author   = models.ForeignKey(User, related_name='author') 

class Discussion(Taggable, Uploadable): 
    author  = models.ForeignKey(User) 
    title  = models.CharField(max_length=250, db_index=True) 
    description = models.TextField(max_length=5000, null=True, 
        blank=True, db_index=True) 
    group  = models.ForeignKey(Group, null=True) 
    timestamp = models.DateTimeField(auto_now_add=True) 

class DiscussionResponse(Uploadable): 
    author  = models.ForeignKey(User) 
    discussion = models.ForeignKey(Discussion) 
    message = models.TextField(max_length=5000) 
    timestamp = models.DateTimeField(auto_now_add=True) 

所以,一个讨论可任选地与一个组相关联,并且DiscussionResponses与讨论有关。我想要做的是找到与组相关的任何讨论(如果存在)并按此排序的最新DiscussionResponse。

据我已经得到就象这样:

Group.objects.filter(some_filtering).distinct().annotate(
    last_response=Max('some__reverse__relationship__timestamp').order_by(
     '-last_response') 

我似乎无法找出正确的方式去在这种情况下,DiscussionResponse时间戳。

更新: 您确实可以通过注释值进行排序。下面是与上一个相关的讨论的时间戳的order_by一个例子:

>>> groups = Group.objects.all().annotate(
     last_response=Max('discussion__timestamp')).order_by('-last_response') 
>>> for group in groups: 
...  print(group.id, group.last_response) 
...  
... 
(2L, datetime.datetime(2013, 5, 8, 15, 32, 31)) 
(1L, None) 
(3L, None) 
(4L, None) 
(6L, None) 
(7L, None) 
(8L, None) 
(9L, None) 

在这种情况下,所以它被移动到顶部只有组#2相关的讨论;其余的则保持自然秩序。但是,我真正想要做的是将最近有响应的群组移动到列表顶部。这就是为什么我认为'discussion__discussionresponse__timestamp'会起作用,但它似乎并没有。

+0

我试过以下,其中没有工作:'discussion__discussionresponse__timestamp','discussion_set__discussionresponse__timestamp'和'讨论set__discussionresponse__timestamp' – foresmac

+0

我不明白你想要完成什么。例如,你声明'last_response = Max(...)'会给你一个时间戳,然后你order_by这个值,你必须按列排序,而不是一个值,我是对吗?你想要的是通过时间戳列的订单?? –

+0

你可以在注释值上加上'order_by';我之前使用过这个技巧。问题是,我似乎无法获得与与群组相关的讨论相关的DiscussionResponses的时间戳。 – foresmac

回答

1

好的,显然它只是'discussion__discussionresponse__timestamp'。我试图在Django的壳,并没有保存新DiscussionResponse后的工作,但它的工作几分钟后,当我再次尝试了:

>>> groups = Group.objects.all().annotate(last_response=Max(
     'discussion__discussionresponse__timestamp')).order_by('-last_response') 
>>> for group in groups: 
...  print(group.id, group.last_response) 
...  
... 
(2L, datetime.datetime(2013, 5, 16, 14, 56, 22)) 
(1L, None) 
(3L, None) 
(4L, None) 
(6L, None) 
(7L, None) 
(8L, None) 
(9L, None) 
>>> 

如果有人知道它为什么没有保存后的工作权利一个新的对象到数据库,但后来工作,这可能是有用的信息。

下面是在与添加到另一个小组讨论/响应只是为了增加验证查询另一个运行:

>>> groups = Group.objects.all().annotate(last_response=Max('discussion__discussionresponse__timestamp')).order_by('-last_response') 
>>> for group in groups: 
...  print(group.id, group.last_response) 
...  
... 
(4L, datetime.datetime(2013, 5, 16, 15, 25, 40)) 
(2L, datetime.datetime(2013, 5, 16, 15, 16, 46)) 
(1L, None) 
(3L, None) 
(6L, None) 
(7L, None) 
(8L, None) 
(9L, None) 
>>> 
+0

随时标记为已回答。 – stellarchariot