2017-02-13 9 views
0

私は小さなチャットアプリを実装するDjango 1.9プロジェクトを持っています。特定の受信者からのすべてのメッセージがダイアログにグループ分けされているので、次のようにモデルが定義されています。Djangoのサブクエリ

class Dialog(models.Model): 
    # Some fields 

class Message(models.Model): 
    dialog = models.ForeignKey(Dialog, ...) 
    text = models.TextField() 
    is_read = models.BooleanField(default = False) 

私の目標は、ダイアログをレンダリングするテーブルでテンプレートをレンダリングすることです。そして、テーブル内の各ダイアログのために、私は未読メッセージ

  • 最後のメッセージのテキストの

    1. を確認する必要があります。

      入力:

      id  dialog_id message   is_read 
      1   1   Hello, sir  false 
      2   1   My name is  true 
      3   1   Jack    true 
      4   2   This site   false 
      5   2   is perfect  false 
      6   2   Cheers   false 
      

      所望の出力:純粋なMySQLで

      dialog_id  last_message_in_dialog  unread_messages_count 
          1     Jack       1 
          2     Cheers      3 
      

      、私はこのようなクエリを記述し、説明の下にモックデータを考慮することが

    select 
         a.dialog_id, 
         text as last_message_in_dialog, 
         (select count(*) from message 
         where dialog_id = a.dialog_id and is_read = false) as unread_messages_count 
    from message a 
    where id in (select max(id) from message group by dialog_id) 
    
    0 Djangoの用語で

    は、私は以下のコードを持っている:

    max_id_qs = Message.objects.\ 
            values('dialog__id').\ 
            annotate(max_id = Max('id'),).values('max_id') 
    
    qs = Message.objects.filter(id__in = max_id_qs).\ 
            values('dialog__id', 'text') 
    

    このコードは、各ダイアログ内の最後のメッセージを取得するためにも機能します。しかし、問題は、Djangoでサブクエリ(select count(*) from message where dialog_id = a.dialog_id and is_read = false)を実装する方法を理解できないことです。たぶんmax_id_qsの私の総合的なアプローチは間違っていますし、Django ORMでクエリを実装するためのよりエレガントで明確な方法がありますか? 私はこの問題を解決しようと一日も過ごしました。お願い助けて !

  • 答えて

    0

    これは動作します: -

    allDistinctIdWithNotReadMsg = 
        Message.objects.filter(is_read=False).values('id').annotate(the_count=Count('is_read',distinct('id'))) 
    
    for ids in allDistinctIdWithNotReadMsg: 
        lastMsg = Message.objects.filter(dialog_id=ids['id']).order_by("-id")[0] 
        for msg in lastMsg: 
    
         print ids['id'] ,msg.message,ids['the_count']