如何编写一个Django过滤器查询,从一个表单中选择多个值,而不需要很多if语句?

bzzcjhmw  于 2022-12-14  发布在  Go
关注(0)|答案(3)|浏览(105)

我有几个Django表单,当提交时,如果表单有效,只需要最低和最高价格,但其他值可能是空的,也可能不是空的,我会这样存储这些值:

max_budget = price_form.cleaned_data['max_price'] #required
    
    max_budget = price_form.cleaned_data['max_price'] #required 
    
    another_value1 = other_form1.cleaned_data['another_value1'] #string
    
    another_value2 = other_form1.cleaned_data['another_value2'] #string
    
    another_value3 = other_form2.cleaned_data['another_value3'] #string
    
    another_value4 = other_form2.cleaned_data['another_value4'] #string
    
    another_value5 = other_form3.cleaned_data['another_value5'] #boolean value
    
    another_value6 = other_form3.cleaned_data['another_value6'] #boolean value

我想查询一个模型(单个数据库表),使用这些变量值作为过滤器,这些变量值对应于数据库中的特定字段。问题是,目前,我不得不使用大量精心设计的嵌套if/else语句,每个语句都包含下面一行的变体,以便根据不同的可能值或缺少值来正确过滤数据库。

query_results = Model.objects.filter(price__range=(min_budget, max_budget), field_in_the_DB="another_value1", field_in_the_DB="another_value2", field_in_the_DB__icontains="another_value3", field_in_the_DB__icontains="another_value4", field_in_the_DB="another_value5", field_in_the_DB="another_value6").order_by("Another_field_in_the_DB_not_related_these_values")

这是因为只需要输入最低和最高价格,所以需要类似这样的内容。

price__range=(min_budget, max_budget)

对于其他变量,提交时可能有的有值,有的为空,那么如何才能有效地过滤DB表,而不需要使用大量的if/else语句来考虑不同的可能值或没有值?有没有更简单的方法?

x0fgdtte

x0fgdtte1#

我使用一个Q过滤器。你不是从“IF”保存的,但你可以让他们订购。

from django.db.models import Q

# this condition must always exist otherwise the filter fails
my_filter = Q( price__range=(min_budget, max_budget) ) 

#I use Get, modify for POST if necessary
if self.request.GET.get("other_value1", ""): 
    my_filter &= Q( field_in_the_DB="other_value1" )
if self.request.GET.get("other_value2", ""):
    my_filter &= Q( field_in_the_DB="other_value2" )
if self.request.GET.get("other_value3", ""):
    my_filter &= Q(field_in_the_DB__icontains="another_value3" )
if self.request.GET.get("other_value4", ""):
    my_filter &= Q(field_in_the_DB__icontains="another_value4" )
if self.request.GET.get("other_value5", ""):
    my_filter &= Q( field_in_the_DB="other_value5" )
if self.request.GET.get(other_value6):
    my_filter &= Q( field_in_the_DB="other_value6" )

query_results = Model.objects.filter(my_filter).order_by("...")

看作业中的&=,希望对你有帮助。

6psbrbz9

6psbrbz92#

您可以使用dict,并在筛选器中将其作为**kwargs传递。
范例

query_params = {
    'field_in_db': value,
    'another_field__icontains': another_value
}

query_results = Model.objects.filter(**query_params)  # the rest of the queryset
yhxst69z

yhxst69z3#

首先,我想对丹尼尔·阿库尼亚说声谢谢,因为你的答案大部分是正确的,你应该得到99.9%的信任。
然而,我确实对if语句进行了更改,因为我意识到它们被跳过了,没有被访问。
下面是我对if语句所做的一些小改动:

if other_value1: 
    my_filter &= Q( field_in_the_DB="other_value1" )
if other_value2:
    my_filter &= Q( field_in_the_DB="other_value2" )
if other_value3:
    my_filter &= Q(field_in_the_DB__icontains="another_value3" )
if other_value4:
    my_filter &= Q(field_in_the_DB__icontains="another_value4" )
if other_value5:
    my_filter &= Q( field_in_the_DB="other_value5" )
if other_value6:
    my_filter &= Q( field_in_the_DB="other_value6" )

相关问题