2013-05-16 231 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