从django上的关系注释列字段

时间:2015-06-19 23:31:42

标签: django python-2.7 django-orm

我有两个模型定义了所有者和狗

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)

我想列出所有业主的清单,其中包含按日期采用的狗数量。

实施例: OwnerName日期金额 理查德15/11/24 2 Jow 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聚合器函数不存在,但也许可以这样做。

提前致谢。

1 个答案:

答案 0 :(得分:2)

如果您将查询更改为

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

这有效,但似乎是hackish,因为它将order_by用于排序以外的目的。如果我遇到更好的方法,我会再次更新。