如何在Django中通过外键存在来命令对象

时间:2014-09-04 06:29:26

标签: python django django-models

我有以下数据库结构

class Item(models.Model):
    id = models.IntegerField(primary_key=True, unique=True)
    pub_date = models.DateTimeField(auto_now_add=True)

class Related(models.Model):
    item = models.ForeignKey(Item)

表格填充了以下数据

[
{"pk": 1, "model": "app.item", "fields": {"pub_date": "2014-09-04T05:31:35.126Z"}}, 
{"pk": 2, "model": "app.item", "fields": {"pub_date": "2014-09-04T05:31:37.733Z"}}, 
{"pk": 3, "model": "app.item", "fields": {"pub_date": "2014-09-04T05:31:38.039Z"}}, 

{"pk": 1, "model": "app.related", "fields": {"item": 1}}, 
{"pk": 2, "model": "app.related", "fields": {"item": 2}}, 
{"pk": 3, "model": "app.related", "fields": {"item": 1}}
]

我需要选择由相关对象(计数> 0)排序的对象。我知道最近的查询语法是:

Item.objects.order_by('-related', '-pub_date')
for item in Item.objects.order_by('-related', '-pub_date'):
    print('%s %s' % (item.pub_date, item.related_set.count()))

我们需要什么(排序不受相关对象数量影响):

2014-09-04 05:31:37.733000+00:00 1
2014-09-04 05:31:35.126000+00:00 2
2014-09-04 05:31:35.126000+00:00 2
2014-09-04 05:31:38.039000+00:00 0

我们得到了什么:

2014-09-04 05:31:35.126000+00:00 2
2014-09-04 05:31:37.733000+00:00 1
2014-09-04 05:31:35.126000+00:00 2
2014-09-04 05:31:38.039000+00:00 0

就SQL而言,我需要:

SELECT * FROM app_item
LEFT OUTER JOIN app_related ON ( app_item.id = app_related.item_id )
GROUP BY app_item.id
ORDER BY COUNT(app_related.id) > 0 DESC, app_item.pub_date DESC

或类似的东西:

Item.objects.annotate(has_related=CountGreaterZero('related')).order_by('-has_related', '-pub_date')

1 个答案:

答案 0 :(得分:0)

使用django aggregation

评论后

更新

据我所知,使用django ORM可以使用2个查询完成。另一种解决方案是使用raw sql query,在这种情况下,您只需要一个。

这是django解决方案,但它会执行两个查询:

对于特定型号:

from django.db.models import Count
from itertools import chain

>>> for item in chain(Item.objects.annotate(num_related=Count('related')).filter(num_related__gt=0).order_by('-pub_date'), Item.objects.annotate(num_related=Count('related')).filter(num_related=0).order_by('-pub_date')):
>>>     print item.pub_date, item.num_related
2014-09-04 06:40:54.175445+00:00 1
2014-09-04 06:40:53.336461+00:00 2
2014-09-04 06:40:54.607874+00:00 0