【问题标题】:Annotate a column field from relation on django从 django 上的关系中注释列字段
【发布时间】:2015-09-06 01:27:24
【问题描述】:

我有两个模型定义为 Owner 和 Dog

class Dog(models.Model):
    name = models.CharField(max_length=255)
    owner = models.ForeignKey(Owner)
    adopted_date = models.DateTimeField()


class Owner(models.Model):
    name = models.CharField(max_length=255)

我想和所有主人一起列出截止日期收养的狗的数量。

示例: 所有者姓名 日期 金额 理查德 15/11/24 2 乔 15/11/24 2

我正在做这个查询

Dog.objects.values('owner', 'adopted_date').annotate(Count('owner')).order_by()

这里的问题是此查询返回所有者 ID 而不是名称。

{
    'owner':1,
    'adopted_date': 'date',
    'owner_count': 2
}

我需要告诉所有者所有者的姓名,例如。

{
    'owner':'Richard,
    'adopted_date': 'date',
    'owner_count': 2
}

任何帮助将不胜感激。


版本

This solution works,但我对此有一些疑问,提出此查询Dog.objects.values('owner__name', 'owner', 'adopted_date').annotate(Count('owner'))

我们可以得到一个好的结果,但我担心性能,这将为值内的每一列生成一个分组,但我不需要分组 owner_name,因为该列不是唯一的。

我正在寻找类似的东西

Dog.objects.values('owner', 'adopted_date').annotate(Count('owner'), Column('owner__name')).order_by()

我知道 Column 聚合器函数不存在,但也许是一种执行此类操作的方法。

提前致谢。

【问题讨论】:

    标签: django python-2.7 django-orm


    【解决方案1】:

    如果您将查询更改为

    Dog.objects.values('owner__name', 'adopted_date').annotate(Count('owner'))
    

    您将获得所需形式的字典列表:

    {
        'owner__name': 'Richard',
        'adopted_date': 'date',
        'owner__count': 2
    }
    

    我实际上在values() 子句的文档中找不到这一点,但在 Django ORM 语法中,通过使用双下划线(即“owner__name”)。


    编辑

    通过上述解决方案,仍然存在如果两只狗的领养日期相同,并且两个不同的主人同名,它们将被分组的问题。如果您想按狗对输出进行分组(这将确保每组有一个所有者,因为每只狗有一个所有者),那么您可以在查询中的任何位置添加.order_by('pk')。

    这行得通,但它看起来很老套,因为它将order_by 用于订购以外的目的。如果我遇到更好的方法,我会再次更新。

    【讨论】:

    • 好的,没错。我现在已经知道该解决方案有效,但我对此表示怀疑。所有者的名字不是唯一的,数据库应该包含 2 个不同的理查兹。该解决方案可以将两个不同的人结果合并为一个。也许也按所有者分组我们可以避免这个问题,但在这种情况下,我们有 owner__name 分组只是为了获取字段值。请查看问题的版本。
    • 啊,是的,我明白你在说什么。我认为解决方案可能是重新添加 order_by,但使用 'id' 作为参数。我会更新我的答案。
    • 我还删除了我的评论,“作为旁注,您也可以删除order_by() 子句 - 我认为没有参数它不会做任何事情。”......我意识到order_by does in fact do something when empty。哇!我正在学习东西。
    • 好的,感谢您的帮助。我只是在值中使用使用所有者的版本。
    猜你喜欢
    • 2020-09-03
    • 1970-01-01
    • 2019-07-21
    • 2013-10-30
    • 2019-09-03
    • 2010-11-03
    • 1970-01-01
    • 2014-05-18
    • 2018-03-21
    相关资源
    最近更新 更多