Python Django ORM多个不同的和按顺序排列的

Python Django ORM多个不同的和按顺序排列的,python,django,python-3.x,django-models,Python,Django,Python 3.x,Django Models,我正在开发一个简单的聊天应用程序。我需要为一个用户查询数据库,以获取用户与其他用户对话的最后一条消息。与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 = model

我正在开发一个简单的聊天应用程序。我需要为一个用户查询数据库,以获取用户与其他用户对话的最后一条消息。与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)
<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>]>
[<CHAT: saeed@saeed.com Message: hello 5 To: ted@ted.com>, <CHAT: marshal@marshal.com Message: hello6 To: saeed@saeed.com>]
我尝试了以下查询:

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')
输出:

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)
<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>]>
[<CHAT: saeed@saeed.com Message: hello 5 To: ted@ted.com>, <CHAT: marshal@marshal.com Message: hello6 To: saeed@saeed.com>]
输出:

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)
<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>]>
[<CHAT: saeed@saeed.com Message: hello 5 To: ted@ted.com>, <CHAT: marshal@marshal.com Message: hello6 To: saeed@saeed.com>]
[,]

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

根据对问题的描述,您将其变得有点过于复杂。您可以使用一个。因此,通过首先对另一个人进行“缩减”,我们可以使用唯一性过滤器:

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')
从django.db.models导入案例F,当
最后消息=self.model.objects.filter(
Q(发送方=用户)| Q(接收方=用户)
).注释(
其他=案例(
当(发送方uid=user\u uid,然后=F('receiver\u uid'))时,
默认值=F('sender_uid'),
输出\字段=CharField()
)
).order_by('other','-created')。distinct('other')

此外,所有
Chat
对象都将有一个额外属性:
other
,因此包含非
用户uid
端。

那么您想要一条消息,即发送或接收的最后一条消息?我觉得有点奇怪,你在这里使用了两条消息。@WillemVanOnsem是的,我想要用户每一次对话的最后一条消息,无论是发送还是接收。谢谢,我试过了,但出现了这个错误:**django.db.utils.ProgrammingError:SELECT DISTINCT ON表达式必须与表达式的初始顺序匹配第1行:SELECT DISTINCT ON(其他)“chat_uChat.”id“,…@Saeed:如果您在
order\u by
函数(作为第一个参数)中添加
'other'
,那么订单将按用户uid在other notcreated@Saeed:我们可以为每个用户获取最新消息,然后手动对最新消息进行排序。但这不会有太大的影响,因为我们已经从数据库中获取了这些消息,所以这最多只能将一个O(n)转换为一个O(n logn)解决方案。通过使用
other
我们可以将元素的数量减少2倍,排序非常简单
sorted(my_qs,key=lambda x:x.created,reversed=True)
。谢谢,现在我认为按顺序创建是多余的