Python Django order_by after distinct()。还是截然不同?
我需要像这样的东西Python Django order_by after distinct()。还是截然不同?,python,django,distinct,annotate,Python,Django,Distinct,Annotate,我需要像这样的东西 user_messages = UserMessage.objects.filter(Q(from_user=user) | Q(to_user=user)).order_by('dialog_id').distinct('dialog_id').order_by('created') 当然,它不起作用。我发现我应该使用annotate(),但这对我来说似乎有点困难,我是Django新手。你能帮我吗?这是我必须实现类似功能的代码。也许对你有用 他认为: queryset =
user_messages = UserMessage.objects.filter(Q(from_user=user) | Q(to_user=user)).order_by('dialog_id').distinct('dialog_id').order_by('created')
当然,它不起作用。我发现我应该使用annotate(),但这对我来说似乎有点困难,我是Django新手。你能帮我吗?这是我必须实现类似功能的代码。也许对你有用 他认为:
queryset = Conversation.objects.filter(Q(user_1=user) | Q(user_2=user)).filter(
Q(messages__sender=user, messages__archived_by_sender=False) |
Q(messages__recipient=user, messages__archived_by_recipient=False)).annotate(
last_activity=Max("messages__created")).order_by("-last_activity")
模型如下:(方法等省略)
这适用于一个应用程序,在该应用程序中,同一用户之间永远不能有多个单独的对话对象,但您可以使用存档功能来存档所有消息(从您的角度),这与从用户的角度删除对话一样。此外,“读取”状态存储在对话中,而不是消息中
为了保证两个用户之间没有多个“对话”对象,对话中的用户_1总是较低的用户ID,而用户_2总是较高的用户ID。(事实上,我没有及时想到这个聪明的想法来实际实现它,因此我使用了复杂且不必要的重写save()
逻辑。但是如果我再次这样做,我也会做这部分,甚至可能调用user\u lower
和user\u higher
等字段来说明问题。)
让我们将视图代码分解为:
获取当前用户为用户1或用户2的所有对话对象。通过筛选器,要求返回的所有对话对象至少有一些当前用户可见的消息尚未存档。对话没有时间戳,但消息有时间戳,因此按最近的活动注释对话列表。然后按带注释的时间戳排序
这避免了任何distinct()工作,因为您正在使用join在对话列表中获取,而不是在消息列表中获取join。查看文档中关于使用
order\u by
和distinct
的说明:不,除非您告诉我们您想要什么,否则我们无法帮助您。你想要的确切结果是什么?
class Conversation(models.Model): # there is only one of these for each pair of users who message one another
user_1 = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="conversations_as_user_1")
user_2 = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="conversations_as_user_2")
read_by_user_1 = models.BooleanField(default=False)
read_by_user_2 = models.BooleanField(default=False)
class Meta:
unique_together = (("user_1", "user_2"),)
class Message(TimeTrackable):
conversation = models.ForeignKey(Conversation, related_name="messages", blank=True, help_text="the conversation between these two users (ALWAYS selected automatically -- leave this blank!)")
sender = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="messages_sent")
recipient = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="messages_received")
text = models.TextField() # flat text, NOT bleached or marksafe
archived_by_sender = models.BooleanField(default=False)
archived_by_recipient = models.BooleanField(default=False)