Select组最新记录

Select latest record in the group with ordering

我在使用 Django ORM 编写查询时遇到问题,我想在每个组中查找最新记录。我将聊天消息放入模型中,我想找到每个用户的最新聊天记录,并在主屏幕上显示每个用户的最新聊天记录以及最新用户的聊天记录,就像在 WhatsApp、Skype 或类似应用程序中一样。目前,我正在使用以下查询,

Chats.objects.all().order_by('user_id', '-date').distinct('user_id')

使用这个我可以得到每个用户的最新聊天记录,但我无法得到正确的顺序。查询结果按照用户在数据库中创建的顺序排列,我理解是正确的,但我想在顶部显示发送最新聊天的用户。

我的Models.py

class Chats(models.Model):
    user_id = models.ForeignKey(User, on_delete=models.CASCADE)
    chat = models.CharField(max_length=1023, null=True, blank=True)
    date = models.DateTimeField(auto_now_add=True)

非常感谢,如果需要任何其他信息,请告诉我。

选项 1:在 Django/Python 层上订购

项目首先按user_id排序,只有在平局的情况下,才取最新日期的项目。但这意味着您最终会为每个用户获得一个 Chats 对象,user_id.

排序

我认为你唯一的选择是在 Django/Python 级别对其进行排序,因此将其包装到一个列表中,然后按 date:

排序
from operator import <strong>attrgetter</strong>

items = list(Chats.objects.order_by('user_id', '-date').distinct('user_id'))
items<strong>.sort(key=attrgetter('date'), reverse=True)</strong>
# work with items

然后在模板中渲染items


选项 2:改为注释 User 模型

另一种选择是注释 User 模型,从而使用 QuerySetUser 个对象:

from django.db.models import <strong>Max, OuterRef, Subquery</strong>

User.objects.filter(
    chats__isnull=False
).annotate(
    last_date=Max('chats__date'),
    last_message=<strong>Subquery(</strong>
        Chat.objects.filter(user_id=OuterRef('pk')).order_by('-date').value('chat')[:1]
    <strong>)</strong>
).order_by('-last_date')

这里的 User 对象将有一个额外的属性 .last_date,带有对象的最新日期时间,.last_message 带有该消息。


Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.