Python 如何在Django中按外键存在对对象进行排序
我有以下数据库结构Python 如何在Django中按外键存在对对象进行排序,python,django,django-models,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": "
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')
使用
评论后更新
据我所知,使用django ORM可以使用2个查询完成。另一个解决方案是使用,在这种情况下,您只需要一个
这是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
这样的查询给我们的结果是: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: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所以我需要类似于此的东西。objects.annotatehas_related=Exists'related'。订购人'-有_related','-pub_date'@mofr在这种情况下使用“num_related”的订单,而不是“num_related”的订单。在你的问题中,你想要降序,所以我设置了降序。看起来你真的想要一个升序。@mofr,在你发表评论后,我已经更新了答案。现在可以了吗?如果是这样,您最好澄清您的问题。num_related>0的项目应按发布日期字段排序。没有相关对象的其他项目应包含在结果中,但应在num_related>0的项目之后,并按发布日期排序。如您所见,排序为。按“num_related”排序,“-pub_date”。你只要按“发布日期”点菜就行了?