简体   繁体   English

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

[英]Django: how to order_by on a related field of a related field

I'm using annotate to add a property to an object which I can then use for order_by. 我正在使用annotate向对象添加属性,然后我可以将其用于order_by。 However, I want to annotate on a field of a relation on a relation. 但是,我想在关系的关系字段上进行注释。 I know I should be able to get to the field somehow using double-underscore notation, but I just can't seem to wrap my head around it. 我知道我应该能够以某种方式使用双下划线符号到达现场,但我似乎无法绕过它。

Here are the models: 以下是模型:

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)

So, a Discussion can optionally be associated with a Group, and DiscussionResponses are associated with a discussion. 因此,讨论可以选择性地与组相关联,并且DiscussionResponses与讨论相关联。 What I would like to do is find the most recent DiscussionResponse on any discussions connected to a Group, if it exists, and sort by that. 我想要做的是找到与组相关的任何讨论的最新DiscussionResponse(如果存在),并按此排序。

I've gotten as far as this: 我已经达到了这个目的:

Group.objects.filter(some_filtering).distinct().annotate(
    last_response=Max('some__reverse__relationship__timestamp').order_by(
        '-last_response')

I just can't seem to figure out the right way to get to the timestamp on a DiscussionResponse in this case. 在这种情况下,我似乎无法找到在DiscussionResponse上获取时间戳的正确方法。

UPDATE: You can indeed order by an annotated value. 更新:您确实可以通过带注释的值进行排序。 Here is an example with an order_by on the timestamp of a related discussion: 以下是相关讨论的时间戳上的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)

In this case, only group #2 has related discussions so it was moved to the top; 在这种情况下,只有组#2有相关的讨论,所以它被移到了顶部; the rest retain the natural order. 其余的保留了自然秩序。 What I'd really like to do, though, is move groups that have recent responses to discussions moved to the top of the list. 不过,我真正想做的是将最近讨论做出回应的移动小组移到了列表的顶部。 That's why I thought 'discussion__discussionresponse__timestamp' would work, but it doesn't seem to. 这就是为什么我认为'discussion__discussionresponse__timestamp'会起作用,但似乎没有。

Ok, apparently it is just 'discussion__discussionresponse__timestamp' . 好了,显然, 只是'discussion__discussionresponse__timestamp' I tried it in the Django shell and it didn't work after saving a new DiscussionResponse, but it worked several minutes later when I tried it again: 我在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)
>>> 

If anyone knows why it didn't work right after saving a new object to the database, but did work later, that would probably be useful information. 如果有人知道为什么它在将新对象保存到数据库之后不能正常工作,但稍后工作,那可能是有用的信息。

Here's another run at the query with discussions/responses added to another group just for added verification: 这是查询的另一次运行,其中讨论/响应已添加到另一个组,仅用于添加验证:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM