【问题标题】:Subquerying in DjangoDjango中的子查询
【发布时间】:2017-07-01 05:36:47
【问题描述】:

我有一个实现小型聊天应用程序的 Django 1.9 项目。来自某个接收者的所有消息都被分组到对话框中,因此模型定义如下:

class Dialog(models.Model):
    # Some fields

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

我的目标是使用呈现对话框的表格来呈现模板。对于表格中的每个对话框,我需要查看

  1. 未读消息
  2. 数量
  3. 最后一条消息的文本。

为了说明,考虑下面的模拟数据:

输入:

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

期望的输出:

dialog_id     last_message_in_dialog      unread_messages_count
    1                  Jack                         1 
    2                 Cheers                        3

在纯mysql中,我会写这样的查询:

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)

在 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 中实现查询有更优雅、更清晰的方法吗? 我花了一整天的时间试图解决这个问题。请帮帮我!

【问题讨论】:

    标签: mysql django orm


    【解决方案1】:

    这将起作用:-

    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'] 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-04
      • 2017-11-08
      • 2020-09-20
      • 2013-11-07
      • 2016-11-30
      • 1970-01-01
      • 1970-01-01
      • 2022-12-15
      相关资源
      最近更新 更多