2010-03-16 68 views
2

我有以下Django模型:Django的查询集顺序通过反向ForeignKey的数量相匹配

class Foo(models.Model): 
    title = models.CharField(_(u'Title'), max_length=600) 

class Bar(models.Model): 
    foo = models.ForeignKey(Foo) 
    eg_id = models.PositiveIntegerField(_(u'Example ID'), default=0) 

我希望返回其有一个包含了包含在eg_idBar对象的反向关系Foo对象的列表值的列表。所以,我有:

id_list = [7, 8, 9, 10] 
qs = Foo.objects.filter(bar__eg_id__in=id_list) 

如何根据其拥有的id_listeg_id值相关Bar对象的数量订购匹配Foo对象?

回答

10

使用Django的可爱aggregation features

from django.db.models import Count 
qs = Foo.objects.filter(
      bar__eg_id__in=id_list 
    ).annotate(
      bar_count=Count('bar') 
    ).order_by('bar_count') 
+0

感谢。只是最近从Django 1.0升级,所以聚合功能对我来说还是比较新的。 – msanders 2010-03-16 14:39:24

+0

作为跟进。我试图将过滤器作为属性添加到我的“Foo”模型对象中。即使我导入'Bar'模型,django shell说'计数'('bar')中的'bar'未被识别。为什么它在我的view.py中工作,但不在我的model.py中?谢谢! – prostock 2010-10-15 18:47:48

1

你可以通过使用aggregation,多especifically annotationorder_by

在你的榜样,那就是:

from django.db.models import Count 

id_list = [7, 8, 9, 10] 
qs = Foo.objects.filter(bar__eg_id__in=id_list) 
qs = qs.annotate(count=Count("bar")) 
qs = qs.order_by('-count')