如何将2个django查询组合成一个具有对象限制的查询

时间:2017-07-06 09:33:57

标签: python django

我在数据库中有多种类型的obj_type

我目前正在做的是

a =  Search_model.objects.filter(obj_type="mall", city=city)[:2]

b = Search_model.objects.filter(obj_type="store", city=city)[:2]

然后将a和b结合起来,它给了我: -

[{"name":"a","obj_type":"mall"}, {"name":"b","obj_type":"mall"}{"name":"c","obj_type":"store"}, {"name":"d","obj_type":"store"}]

我想要的是这样的

    if not search_in == None:
        search_in_queries = [q for q in re.split(",", search_in) if q]

        for query in search_in_queries:
            search_in_dict.append(('obj_type__contains', query))

        search_in_query = [Q(x) for x in search_in_dict]
    else:
        search_in_query = None

使search_in的值为" mall,store"

a =  Search_model.objects.filter(reduce(operator.or_, search_in_query), city=city)[:4]

但它给了我所有商场类型obj

[{"name":"a","obj_type":"mall"}, {"name":"b","obj_type":"mall"}{"name":"c","obj_type":"mall"}, {"name":"d","obj_type":"mall"}]

所以我的查询是如何在一个查询中实现上述结果

2 个答案:

答案 0 :(得分:2)

您是否尝试过使用列表用户__in进行搜索。因此,构建一个要过滤的事物列表。

Search_model.objects.filter(obj_type__in=["mall", "store"], city=city)

请参阅:https://docs.djangoproject.com/en/1.11/ref/models/querysets/#in

答案 1 :(得分:0)

如果是Postgres,您可以使用ROW_NUMBER和原始SQL:

Search_model.objects.raw("SELECT id, obj_type from (
        SELECT t.*, ROW_NUMBER() OVER (PARTITION BY obj_type) AS rn 
        FROM search_model t
    ) WHERE rn < 3 and obj_type in ('mall', 'store')"
);

不喜欢这种方式,因为最后我检查过sqlite3没有ROW_NUMBER

对于SqlLite3,您可以触发:

SELECT id, obj_type
FROM search_model t1 
WHERE id in ( 
   select id from search_model t2 
   where t2.obj_type = t1.obj_type 
   order by t2.obj_type desc limit 2
) 
ORDER BY id, obj_type DESC;

使用Django ORM,我们可以look into,在内部,可以构造,过滤,切片,并且通常传递QuerySet而不实际访问数据库:

from django.db.models import Q

mall_items = Search_model.objects.filter(obj_type="mall", city=city).values_list("id", flat=True)[:2]
store_items = Search_model.objects.filter(obj_type="store", city=city).values_list("id", flat=True)[:2]

print Search_model.objects.filter(Q(id__in=mall_items)|Q(id__in=store_items))