2014-09-04 75 views
1

我有以下的数据库结构如何订购的外键所有脑干对象在Django

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}} 
] 

,我需要选择项目对象对象存在(count> 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') 

回答

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 
+0

这样的查询给我们: '2014年9月4日05:31:35.126000 + 00 :00 2 2014-09-04 05:31:37.733000 + 00:00 1 2014-09-04 05:31:38.039000 + 00:00 0' 首先需要更多相关对象数量的项目。订购我需要的: '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' 所以我需要这样的东西 Item.objects.annotate(has_related = Exists('related'))。order_by(' - has_related','-pub_date') – mofr 2014-09-04 06:54:56

+0

@mofr在这种情况下使用'order_by('num_related')',而不是'order_by(' - num_related')'。在你的问题你想要一个DESCending命令,所以我设置降序。看起来你真的想要一个ASCending命令。 – stalk 2014-09-04 06:57:47

+0

@mofr,我已在你评论后更新了答案。现在好吗?如果是这样,你最好澄清你的问题。 – stalk 2014-09-04 07:00:22