Django ORM多个不同且按

时间:2018-09-01 10:08:43

标签: python django python-3.x django-models

我在一个简单的聊天应用程序上工作。我需要查询db的用户,以获取与其他用户的用户对话的最后一条消息。与whatsapp和电报的主页相同。

型号:

class CHAT(models.Model):
    sender_uid = models.CharField(max_length=150, db_index=True)
    receiver_uid = models.CharField(max_length=150, db_index=True)
    message = models.TextField(verbose_name='Message Text')
    created = models.IntegerField(default=created_time_epoch)

我尝试了以下查询:

message_list = self.model.objects.filter(Q(sender_uid=user_uid)|Q(receiver_uid=user_uid)).order_by('receiver_uid', 'sender_uid', '-created').distinct('receiver_uid', 'sender_uid')

输出:

<QuerySet [<CHAT: ted@ted.com Message: hello 4 To: saeed@saeed.com>, <CHAT: marshal@marshal.com Message: hello6 To: saeed@saeed.com>, <CHAT: saeed@saeed.com Message: hello 5 To: ted@ted.com>]>

我的问题是,每次对话我都会收到两条最后一条消息(如果两个用户都互相发送消息),其中一个用户是发送者,另一个用户是接收者。

目前,我使用以下代码进行处理:

message_send_list = list(self.model.objects.filter(sender_uid=user_uid).order_by('receiver_uid', '-created').distinct('receiver_uid'))
message_receive_list = list(self.model.objects.filter(receiver_uid=user_uid).order_by('sender_uid', '-created').distinct('sender_uid'))
temp_list = []
for s_message in message_send_list:
    r_message = next((item for item in message_receive_list if item.sender_uid == s_message.receiver_uid), None)
    if r_message is not None:
        message_receive_list.pop(message_receive_list.index(r_message))
        if s_message.created > r_message.created:
            temp_list.append(s_message)
        else:
             temp_list.append(r_message)
    else:
        temp_list.append(s_message)
temp_list.extend(message_receive_list)

输出:

[<CHAT: saeed@saeed.com Message: hello 5 To: ted@ted.com>, <CHAT: marshal@marshal.com Message: hello6 To: saeed@saeed.com>]

我的问题是如何在一个查询中获得此结果?问题是用户可以是消息的发送者和接收者,而我无法区分哪个是会话的最后一条消息。如何对此进行过滤或区分?

1 个答案:

答案 0 :(得分:1)

根据问题的描述,您将其变得有点复杂。您可以使用the documentation获取其他人。因此,首先在与他人交往时进行“简化”,然后可以为此使用唯一性过滤器:

var xhr = new XMLHttpRequest();
xhr.responseType = 'blob'; // tell XHR that the response will be a pdf file
xhr.onload = function() {
    var blob = this.response;
    var a = window.document.createElement('a');
    a.href = window.URL.createObjectURL(blob);
    a.download = "tst.pdf";
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
};

另外,所有from django.db.models import Case, F, When last_messages = self.model.objects.filter( Q(sender_uid=user_uid) | Q(receiver_uid=user_uid) ).annotate( other=Case( When(sender_uid=user_uid, then=F('receiver_uid')), default=F('sender_uid'), output_field=CharField() ) ).order_by('other', '-created').distinct('other')对象将具有一个额外的属性:Chat,因此包含非other一侧。