0

我有一个包含 13 个复选框的表单,这些复选框共同构成了我的搜索条件……除了我还为 ALL 或 ANY 添加了一对单选按钮。

我希望能摆脱一些优雅的事情,比如:

priority_ids = request.GET.getlist("priority")  # checkboxes
collection   = request.GET.get("collection")    # radio buttons
priorities = []
for priority_id in priority_ids:
    priorities.append(Q(focus__priority=priority_id))
if   (collection == "any"): qset = any(priorities)
elif (collection == "all"): qset = all(priorities)

但是,any() 和 all() 返回一个布尔值,而不是我可以在过滤器中使用的查询集。我想要一个与“Q(...) | Q(...) | Q(...)”或“Q(...) & Q(.. .) & Q(...)" 适用于 1 到 13 个标准。

4

2 回答 2

2

Django 无需为此做任何事情。您只需要将您的Q-s 与&和 分别|以一个简单的循环或更紧凑的方式与reduce.

关于术语,在我看来,您正在调用Q查询集,但事实并非如此。它是查询集上的过滤器。像下面这样的东西应该可以工作:

priority_ids = request.GET.getlist("priority")
collection   = request.GET.get("collection")
priority_filters = []
for priority_id in priority_ids:
    priority_filters.append(Q(focus__priority=priority_id))

base_qs = SomeModel.objects.all()

if collection == "any":
   filtered_qset = base_qs.filter(reduce(operator.or_, priority_filters))
elif collection == "all":
   filtered_qset = base_qs.filter(reduce(operator.and_, priority_filters))
于 2012-04-05T22:56:00.307 回答
0

您可以使用 Q() 动态查询,如下所示...

from django.db.models import Q 
from priority_app.models import Priority  # get your model identified


#(whatever API place you had this):

    priority_id = request.GET.get("priority")   #getlist is isn't a proper list
    field_id = request.query_params.get('collection')
    if priority_id:
        priority_id_list = list(map(str.strip, priority_id.split(",")))


        dynamic_query_filters = Priority.objects.none()
        for a_item in priority_id_list:
            if collection == "any":
                dynamic_query_filters |= (Q(id=a_item))    # OR query
            else:
                dynamic_query_filters &= (Q(id=a_item))   # AND query
    
        queryset = Priority.objects.filter(dynamic_query_filters)   
        # you will notice, it executes in order of "query", maybe take them in different variables and chain them accordingly.
       
 
于 2021-01-14T17:27:58.730 回答