2016-05-18 113 views
0

我有一個Conversation模型和一個Message模型。 Message有一個日期字段date_creationDjango:如何通過基於外鍵的「order by」過濾器

Conversation通過messages這樣有一個多對多Message

class Message(models.Model): 
    date_last_modif = models.DateTimeField(auto_now=True) 
    src = models.ForeignKey('User', related_name='message_src') 
    dst = models.ForeignKey('User', related_name='message_dst') 
    is_read = models.BooleanField(default=False) 
    message = models.TextField(null=True, blank=True) 

class Conversation(models.Model): 
    messages = models.ManyToManyField(Message, related_name='conversations') 

我想要做的就是讓一切都沒有讀消息,由最近的消息下令第一的談話

因此,這裏是我的第一個過濾器,其得到所有有消息尚未閱讀的對話:

p = current_user # code omitted for sake of clarity 
convs_not_read = Conversation.objects.filter(
    Q(messages__dst=p, messages__is_read=False)).distinct() 

請注意,我需要不同的只得到會話ID的一次,否則,如果有超過一個未讀取的消息,您將獲得與此對話中未讀取消息相同的id。

從現在開始,我試圖讓所有對話都有「沒有」未讀取的消息,並通過排列最近的消息

我已經開始:

convs_read = Conversation.objects 
     .filter(messages__dst=p) 
     .exclude(pk__in=convs_not_read.values_list('id', flat=True)) 
     .distinct() 

這工作,但他們沒有被最近的消息過濾。我被困在這裏。你會怎麼做?

如果我嘗試:在此查詢添加.order_by('-messages__date_last_modif')任何地方,它沒有任何效果,在這裏:

 .filter(messages__dst=p) 
     .order_by('-messages__date_last_modif') 
     .exclude(pk__in=convs_not_read.values_list('id', flat=True)) 
     .distinct() 

...或在這裏:

 .filter(messages__dst=p) 
     .exclude(pk__in=convs_not_read.values_list('id', flat=True)) 
     .distinct() 
     .order_by('-messages__date_last_modif') 

...不會改變結果

+0

你試過'convs_read = convs_read.order_by(' - messages__date_last_modif')'? –

+0

是的,我會更新我的問題 –

回答

-1

我這樣做「之類的」手工:通過郵件日期我第一次排序,然後對每封郵件,我加了談話的pk如果它尚未添加。我很確定這不是最優化的解決方案,所以如果你有任何建議基於這種工作解決方案,我是你的男人!

l = [] 
for m in Message.objects.filter(dst=p).order_by('-date_last_modif'): 
    for c in m.conversations.all(): 
     if c not in l: 
      l.append(c.pk) 
conversations_read = [c for c in Conversation.objects.filter(pk__in=l)] 
+0

對不起,我希望我能有時間,但現在我沒有時間 –

0

嘗試使用:

my_query.order_by('-conversations__date_last_modif') 

,因爲你正在使用related_name作爲"conversations"