python - Django:如何在相关字段的相关字段上排序

标签 python django sql-order-by annotate

我正在使用 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)

因此,可以选择将讨论与组相关联,并且讨论响应与讨论相关联。我想做的是找到与组相关的任何讨论的最新 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' 会起作用,但它似乎不起作用。

最佳答案

好吧,显然它只是'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)
>>> 

关于python - Django:如何在相关字段的相关字段上排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16594862/

相关文章:

python - 如何使用 Python 扩展我的 facebook access_token?

python - Django 信号文件,无法导入模型名称

Django模型添加uuid

php - 按日期时间显示来自多个表的数据

MySql 不使用带有 ORDER BY 的索引

mysql - 一周中最好的一天

python - 具有多表继承的 Django 1.11 上的可能错误或 python 3.5 上的可能错误还是我?

python - NumPy 数组的反向堆叠操作

django - Django项目中每个应用程序的不同错误处理程序

jquery - 从 django 应用程序到 jquery 插件的依赖