如何将2 Django查询合并为一个带有对象限制的查询

43 阅读2分钟

开发人员需要将两个Django查询合并为一个,并在合并后的查询中限制对象的数量。该查询需要能够根据obj_typecity参数过滤对象。

解决方案

使用 __in 运算符

一种解决方案是使用 __in 运算符将不同的 obj_type 值合并为一个查询。__in 运算符允许将多个值传递给查询,并返回与其中任何一个值匹配的对象。

以下是一个使用 __in 运算符合并两个查询的示例:

from django.db.models import Q

search_in_queries = [
    Q(obj_type__contains=query) for query in search_in_queries
]
combined_query = Q(reduce(operator.or_, search_in_queries), city=city)
objects = Search_model.objects.filter(combined_query)[:4]

使用 Q 对象

另一种解决方案是使用 Q 对象。Q 对象允许将多个查询组合成一个更复杂的查询。

以下是一个使用 Q 对象合并两个查询的示例:

from django.db.models import Q

first_query = Q(obj_type="mall", city=city)
second_query = Q(obj_type="store", city=city)
combined_query = first_query | second_query
objects = Search_model.objects.filter(combined_query)[:4]

代码例子

以下是一个完整的代码示例,演示如何将两个Django查询合并为一个,并在合并后的查询中限制对象的数量:

from django.db.models import Q

def get_objects(search_in, city, limit=4):
    if search_in is not None:
        search_in_queries = [q for q in re.split(",", search_in) if q]
        search_in_dict = []
        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

    combined_query = Q(reduce(operator.or_, search_in_query), city=city)
    objects = Search_model.objects.filter(combined_query)[:limit]
    return objects

这个函数接受三个参数:search_incitylimitsearch_in 参数是需要过滤的对象类型列表,city 参数是需要过滤的城市,limit 参数是需要返回的对象数量。

函数首先检查 search_in 参数是否为 None。如果 search_in 参数为 None,则函数将使用 Q 对象创建一个查询,该查询将匹配所有对象,而不管其 obj_type 值如何。

如果 search_in 参数不为 None,则函数将创建一个 search_in_queries 列表,该列表包含 search_in 参数中指定的每个 obj_type 值。

接下来,函数创建一个 search_in_dict 列表,该列表包含一个元组列表,其中每个元组包含一个对象类型的 obj_type__contains 比较和该类型的名称。

然后,函数创建一个 search_in_query 列表,该列表包含 search_in_dict 列表中每个元组的 Q 对象。

最后,函数创建一个 combined_query 对象,该对象使用 reduce() 函数将 search_in_query 列表中的所有 Q 对象组合在一起。combined_query 对象然后与 city 参数一起传递给 filter() 方法,以获取所有匹配 combined_query 对象并位于指定城市的对象。

[:limit] 切片用于限制返回的对象数量。