如何为每个给定的外键列表获取n个项目?

时间:2018-02-21 10:51:50

标签: python django django-queryset django-orm

我试图找出一种在最短的时间内执行此查询的方法。

number_of_results = 25
results = []
foreign_keys = [1,2,3,4,5]
for key in foreign_keys():
    results.append(Model.objects.filter(foreign_key=key)[:number_of_resutlts])

即使它是单个查询集,也没关系。我想要完成的是减少数据库查询的数量。我的数据库是PostgreSQL 10。

如何进一步简化此操作?

3 个答案:

答案 0 :(得分:0)

从Django 1.11开始,在这种情况下你可以使用QuerySet的union方法:

qs = Model.objects.filter(foreign_key=foreign_keys[0])[:number_of_results]

for fk in foreign_keys[1:]:
    qs = qs.union(Model.objects.filter(foreign_key=fk)[:number_of_results])

https://docs.djangoproject.com/en/1.11/ref/models/querysets/#union

答案 1 :(得分:0)

这是group by and select n问题。

通过Django实现这一目标似乎没有单步操作。但是,使用联合,我们可以使用单个查询命中数据库以获得结果。 Union内部有自己的成本 - 单独运行查询并选择不同的等等。

一种方法是使用原始sql:

objs = Model.objects.raw(
                """SELECT rank_filter.* FROM (SELECT model.*, rank() 
                OVER (PARTITION BY foreign_key_id ORDER BY created DESC) 
                FROM model WHERE foreign_key_id IN (1,2,3,4,5)) 
                rank_filter WHERE RANK <= n""") # replace n with 25

for obj in objs:
    # do something

答案 2 :(得分:0)

试试这个:

results.append(Model.objects.filter(foreign_key__in=key)[:number_of_resutlts])