Python Django ORM多个不同的和按顺序排列的
我正在开发一个简单的聊天应用程序。我需要为一个用户查询数据库,以获取用户与其他用户对话的最后一条消息。与whatsapp和电报的主页相同 型号: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
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)
。谢谢,现在我认为按顺序创建是多余的