我有以下数据库结构
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')
答案 0 :(得分:0)
更新。
据我所知,使用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