我使用annotate向对象添加属性,然后我可以将其用于order_by。但是,我想在关系的关系字段上进行注释。我知道我应该能够以某种方式使用双下划线符号到达现场,但我似乎无法绕过它。
以下是模型:
class Group(Taggable, Uploadable):
name = models.CharField(max_length=250, db_index=True)
description = models.TextField(max_length=5000, null=True,
blank=True, db_index=True)
private = models.BooleanField(default=False)
members = models.ManyToManyField(User, null=True,
related_name='members', through='GroupToUser')
pending_members = models.ManyToManyField(User, null=True,
related_name='pending_members')
admin = models.ForeignKey(User, null=True)
timestamp = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(User, related_name='author')
class Discussion(Taggable, Uploadable):
author = models.ForeignKey(User)
title = models.CharField(max_length=250, db_index=True)
description = models.TextField(max_length=5000, null=True,
blank=True, db_index=True)
group = models.ForeignKey(Group, null=True)
timestamp = models.DateTimeField(auto_now_add=True)
class DiscussionResponse(Uploadable):
author = models.ForeignKey(User)
discussion = models.ForeignKey(Discussion)
message = models.TextField(max_length=5000)
timestamp = models.DateTimeField(auto_now_add=True)
因此,讨论可以选择与一个组相关联,而DiscussionResponses与讨论相关联。我想做的是找到与群组相关的任何讨论的最新DiscussionResponse(如果存在),并按此排序。
我已经达到了这个目的:
Group.objects.filter(some_filtering).distinct().annotate(
last_response=Max('some__reverse__relationship__timestamp').order_by(
'-last_response')
在这种情况下,我似乎无法找到在DiscussionResponse上获得时间戳的正确方法。
更新
您确实可以通过带注释的值进行排序。以下是相关讨论时间戳上order_by
的示例:
>>> groups = Group.objects.all().annotate(
last_response=Max('discussion__timestamp')).order_by('-last_response')
>>> for group in groups:
... print(group.id, group.last_response)
...
...
(2L, datetime.datetime(2013, 5, 8, 15, 32, 31))
(1L, None)
(3L, None)
(4L, None)
(6L, None)
(7L, None)
(8L, None)
(9L, None)
在这种情况下,只有第2组有相关的讨论,所以它被移到了顶部;其余的保留了自然秩序。不过,我真正想做的是将最近回复的移动群体移到列表顶部的讨论中。这就是为什么我认为'discussion__discussionresponse__timestamp'
会起作用的原因,但它似乎并不适用。
答案 0 :(得分:1)
好吧,显然 只是'discussion__discussionresponse__timestamp'
。我在Django shell中尝试过它,在保存一个新的DiscussionResponse之后它没有用,但是几分钟后我再次尝试它时它起作用了:
>>> groups = Group.objects.all().annotate(last_response=Max(
'discussion__discussionresponse__timestamp')).order_by('-last_response')
>>> for group in groups:
... print(group.id, group.last_response)
...
...
(2L, datetime.datetime(2013, 5, 16, 14, 56, 22))
(1L, None)
(3L, None)
(4L, None)
(6L, None)
(7L, None)
(8L, None)
(9L, None)
>>>
如果有人知道为什么它在将新对象保存到数据库之后不能正常工作,但之后确实有效,那么这可能是有用的信息。
此处是查询的另一次运行,其中讨论/响应已添加到另一个组,仅用于添加验证:
>>> groups = Group.objects.all().annotate(last_response=Max('discussion__discussionresponse__timestamp')).order_by('-last_response')
>>> for group in groups:
... print(group.id, group.last_response)
...
...
(4L, datetime.datetime(2013, 5, 16, 15, 25, 40))
(2L, datetime.datetime(2013, 5, 16, 15, 16, 46))
(1L, None)
(3L, None)
(6L, None)
(7L, None)
(8L, None)
(9L, None)
>>>