在Django queryset

时间:2018-07-21 16:28:03

标签: django django-models django-orm

class User(models.Model):
    name = models.CharField(max_length=189)

class Chat(models.Model):
    message = models.TextField()
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="messages")
    created_at = models.DateTimeField(auto_now_add=True)

我想在这里做的是,我要获得一个查询集,该查询集是根据用户的最后一条消息时间排序的,该查询集还将包含用户的最后一条消息作为附加数据。

我尝试了以下方法。

qs = User.objects.annotate(
        last_message_time=Max("messages__created_at"),
        last_message=F("messages__message")
     ).order_by("-last_message_time")

在这里,我得到的是最后一条消息时间,但是是用户的第一条消息。

2 个答案:

答案 0 :(得分:1)

我认为您只需要一个查询就可以轻松完成。 This看起来完全符合您的需求。

您可以编写一个自定义的原始SQL查询来获取所需的内容,也可以通过两步来执行效率不高的操作:

qs = User.objects.annotate(
       last_message_time=Max("messages__created_at"),
    ).order_by("-last_message_time")

for user in qs:
    user.last_message = Chat.objects.get(user=user, created_at=user.last_message_time)

答案 1 :(得分:1)

我想我已经找到答案了。

qs = User.objects.annotate(
        last_message_time=Max("messages__created_at"),
        last_message_message=Subquery(
            Chat.objects.filter(user=OuterRef("id")).order_by("-created_at").values("message")[:1]
        )
     ).order_by("-last_message_time")

我从本文中获得了有关此问题的帮助! https://medium.com/@hansonkd/the-dramatic-benefits-of-django-subqueries-and-annotations-4195e0dafb16