在Django中,有一种方法可以聚合与相关对象上的条件的关系

时间:2012-08-24 03:42:16

标签: python sql django django-queryset

Django聚合文档给出了这个示例,该示例计算与每个Book相关的Publisher个数,并返回一个查询集,其中前5个发布者使用其书计数进行注释(如添加新字段)这个计数):

>>> pubs = Publisher.objects.annotate(num_books=Count('book')).order_by('-num_books')[:5]
>>> pubs[0].num_books
1323

但我需要只计算一种特定类型的书。像。的东西。

>>> pubs = Publisher.objects.annotate(num_books=Count('book__type="nonfiction"')).order_by('-num_books')[:5]

我是否可以使用过滤器来完成此操作,还是需要使用原始SQL?

上面的文档示例类似于我的实际问题,即当系统和医院都被建模为医疗保健时,通过系统中的医院数量来识别和量化最大的医疗组Entity:< / p>

>>> biggest_systems = Entity.objects.filter(relationships__type_id=NAME_TO_TYPE_ID.get('hospital')).annotate(num_hospitals=Count('relationships')).order_by('-num_hospitals')[:5]
>>> biggest_systems[0].num_hospitals
25

relationships是一个带有直通表的实体M2M字段,type_id也是实体中的一个字段:

class Entity(models.Model):
    id = models.AutoField(verbose_name='ID',primary_key=True, db_column='ID') 
    type_id = models.IntegerField(verbose_name='detailed type',db_column='TypeID', blank=True, editable=True, choices=ENTITYTYPE_CHOICES, help_text="A category for this healthcare entity.")
    relationships = models.ManyToManyField('self', verbose_name='affiliated with', through='EntityRelationship', symmetrical=False, related_name='related_to+')

1 个答案:

答案 0 :(得分:3)

请参阅Order of annotate() and filter() clauses

Publisher.objects.filter(book__rating__gt=3.0).annotate(num_books=Count('book'))

或者在你的情况下:

Publisher.objects.filter(book__type='nonfiction').annotate(num_books=Count('book'))