我需要类似的东西

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的新手。 你能帮助我吗?

===============>>#1 票数:1 已采纳

这是我必须实现类似功能的代码。 也许它将对您有用。

在视图中:

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")

模型看起来像:(省略了方法等)

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)

这是针对一个应用程序的,在该应用程序中,同一用户之间永远不会有多个单独的对话对象,但是可以使用存档功能(从您的角度)存档所有消息,这与从用户的角度删除对话一样好。 同样,“已读”状态存储在对话中,而不存储在消息中。

为了保证没有两个用户具有多个“对话”对象,对话中的user_1始终是较低的用户ID,而user_2始终是较高的用户ID。 (实际上,我并没有及时想到这个聪明的想法来实际实现它,所以我拥有复杂且不必要的覆盖save()逻辑。但是如果我再做一次,我也会做这部分,也许甚至调用字段user_loweruser_higher或类似的名称即可。)

让我们分解视图代码:

提取当前用户为user_1或user_2的所有对话对象。 通过过滤器,要求返回的所有对话对象都至少没有归档当前用户可见的某些消息。 对话没有时间戳,但是消息有时间戳,因此请按最新活动为对话列表添加注释。 然后按带注释的时间戳排序。

这样可以避免任何distinct()工作,因为您是在使用联接的会话列表中而不是在使用联接的消息列表中访存。

  ask by Alexander O translate from so

未解决问题?本站智能推荐:

1回复

Django-如何在字段不同后获得最大值

我有那些模型: 产品表包含一些产品(...) 每次商店更改产品价格时,价格表都会更新。 我想从每个商店获取最新价格(“当前价格”),然后获取每个产品的最高价格和平均价格。 我首先尝试了一种产品: 但得到: 我还尝试添加order_by('-price')
1回复

在Django注释中过滤相关字段

我开始学习Django,这是我的第一次编程经验。 我有下一个型号: 我需要按至少有一个人的地区组织来分组。 要获得至少有一个我尝试过的组织的质量保证,请执行以下操作: 但是,由于比率为一对多,对吗? 结果相等,但是我不确定第一个版本是否正确。 区域0 4
1回复

Django:如何在相关字段的相关字段上order_by

我正在使用annotate向对象添加属性,然后我可以将其用于order_by。 但是,我想在关系的关系字段上进行注释。 我知道我应该能够以某种方式使用双下划线符号到达现场,但我似乎无法绕过它。 以下是模型: 因此,讨论可以选择性地与组相关联,并且DiscussionRespon
1回复

django:order_by和独特的OK; 然后order_by另一个字段...如何?

我不知道该怎么做...看似简单,但我却做不到...请给我一个提示。 这是模型: 事件表包含许多事件,并且同一PointOfInterest可能有多个事件。 我的目标是选择从今天开始(我的住所附近有明显事件)的前10个事件。 对于每个PointOfInterest ,新列表只有一个条
1回复

Django:在annotation()和value()之后聚合到特定级别

我正在尝试使用Django将值聚合到特定级别,但似乎并不简单:聚合发生在完整的查询集或对象级别,而不是“中间”。 这是我的查询:我需要根据多个事件条目按年计算总活动时间。 结果,我得到以下结果: 而不是像这样的东西: 为了设置聚合级别,我需要类似: 汇总(
1回复

Django:使用前缀和注释模型

我有一个TimeTrial模型,该模型汇总了Leg的有序列表。 ( 实际模型的精简版。) 所述TimeTrialManager注释每TimeTrial与数量Leg S和的总和Leg.duration 。 我想以类似的方式使用Django的annotate / aggregate来
1回复

Django计算聚合总数

我正在尝试构建一个基于用户ID聚合统计信息的表。 这是第一次提出问题,如果我错过任何重要的话,请耐心等待。 这是模型: 这是观点: 我遇到的问题是avg,slg,obp和ops都是模型中的所有计算,并且在View中对它们求平均值是平均值,而不是计算根据玩家ID聚合的总数。
1回复

Django意外注释F()/ F()“四舍五入”

我有一个Django 1.9 queryset qs,向其中添加了以下注释: 奇怪的是,结果似乎向下舍入(如Math.floor),因此我得到以下结果(示例): 同样,可能是这种情况仅在从Django 1.7升级到Django 1.9之后发生。 我是在做错什么还是一个错误?
1回复

Django:无法在模板表上进行GROUP BY

我正在尝试在模板中显示一个表格,该表格显示交易及其日期。 查询是: 但是用户可以选中一个复选框,如果将其设置为true,则该表格中的每个日期应显示一行。 没有分组依据: 我想做的是: 我已经尝试过 使用注释,但不起作用! 我真的还不知道如何分组。
1回复

Django 1.8。 当我们在值中使用id字段并在Django中注释操作时,结果sql-query中将忽略其他字段

我想将Django从1.7.11更新到1.11.18。 但是我发现了一个问题。 Django针对不同的Django版本进行不同的sql查询。 例如。 我有一个查询: Django 1.7.11的sql-query: SELECT `member_account`.`id`,