Django分发过滤器结果 [英] Django distribute filter results

查看:87
本文介绍了Django分发过滤器结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Django应用中,我正在执行如下查询:

In a Django app, I am doing query like below:

Products.objects.filter(category_id=[1, 2, 3])[:6]

我从类别1中取回6个项目.我想要的是从每个类别2个项目中获得.

I am getting back 6 items from category 1. What I want is form each category 2 items.

或者,我尝试使用Q,如下所示:

Alternatively I tried with Q like below:

Products.objects.filter(Q(category_id=1)|Q(category_id=2)|Q(category_id=3))[:6]

我可以获得所有结果,然后遍历结果以进行筛选,依此类推.结果查询集很大.

I can get all the results and then iterate through the results to filter out and so on. The resulted query set is pretty large.

如何在不迭代整个查询集的情况下使用Django ORM通过单个查询进行查询?

How can I make that query using Django ORM via single query without iterating through the whole queryset?

推荐答案

我看不到任何直接的方法.我能想到的一些解决方法:

I do not see any direct way to do that. Some workarounds I can think of:

最直接的方法,仅涉及一个查询.请记住使用迭代器,这样您就不必使用内存中的完整查询集.

The most direct way, only involve one query. Remember to use iterator so you don't have the full queryset in memory.

for product in Products.objects.filter(category_id__in=[1, 2, 3]).iterator():
    # Add some logic to select your six items.

当然,根据迭代顺序的不同,这可能会很耗时(例如,如果您首先插入了所有类别1项目).随机地 .order('?') 请注意它有一些警告(主要是很慢).

Of course depending on the iteration order it could be time consuming (for instance if all your category 1 items were inserted first). Throwing a random order .order('?') may help but be careful that it have some caveats (mainly, it's slow).


[
    p
    for category_id in [1, 2, 3]
    for p in Products.objects.filter(category_id=category_id)[:2]
]

结果不再是查询集,但这可能无关紧要.

The result is not a queryset anymore, but that may not matter.


获取每个类别的第一个类别,将它们排除在外,然后获取第二个类别.

Get the first of each categories, exclude them and then get the second ones.

ids = [1, 2, 3]
items = list(Products.objects.filter(category_id__in=ids).distinct('category'))

items += list(Products.objects.filter(category_id__in=ids).exclude(
    id__in=[i.id for i in items],
).distinct('category'))

需要注意的是,它不再是查询列表,而是列表,并且还可以看到

Same caveat that it's a list and not a queryset anymore and also see the limitations on distinct(*field).

这篇关于Django分发过滤器结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆