减少elif块的数量

时间:2017-07-21 11:45:27

标签: python django django-rest-framework query-optimization

我尝试根据以下queryparams进行过滤。

如何减少代码行:

if fridge == 'true' and toilet == 'true' and side_window == 'true':
    queryset = queryset.filter(toilet=True, fridge=True, sun_side_window=True)
elif fridge == 'true' and toilet == 'true':
    queryset = queryset.filter(toilet=True, fridge=True)
elif fridge == 'true' and side_window == 'true':
    queryset = queryset.filter(sun_side_window=side_window.capitalize(), fridge=fridge.capitalize())
elif toilet == 'true' and side_window == 'true':
    queryset = queryset.filter(sun_side_window=side_window.capitalize(), toilet=toilet.capitalize())
elif fridge == 'true':
    queryset = queryset.filter(fridge=fridge.capitalize())
elif toilet == 'true':
    queryset = queryset.filter(toilet=toilet.capitalize())
elif side_window == 'true':
    queryset = queryset.filter(sun_side_window=True)

3 个答案:

答案 0 :(得分:4)

我假设'true'.capitalize()代表布尔值True,而不是字符串'True'

首先,将'true'转换为True。 然后,构建一个包含要传递给queryset.filter的关键字参数的字典。 我在一个字典理解中执行这两个步骤:

vars = {'fridge': fridge, 'toilet': toilet, 'side_window': side_window}
kwargs = {kw: True for kw in vars if vars[kw] == 'true'}

如果您不熟悉理解,这相当于:

kwargs = {}
for kw in vars:
    if vars[kw] == 'true':
        kwargs[vars] = True

然后解压缩此词典,并将其传递给queryset.filter

queryset = queryset.filter(**kwargs)

解压缩字典相当于将其键/值对作为关键字参数传递给函数。

f(a=1, b=2)
# is equivalent to
kw = {'a': 1, 'b': 2}
f(**kw)

作为旁注,我不知道queryset,但它看起来像一个模块。 如果是这样,我建议不要将queryset.filter的结果重新分配给queryset ......

答案 1 :(得分:0)

如何创建像

这样的功能
def q(**kwargs):

    for k in kwargs:
        if kwargs[k] == 'true':
            kwargs[k] = True

    return queryset.filter(**kwargs)

您只需要以某种方式将sun_side_window映射到side_window,或将其删除。

答案 2 :(得分:0)

k = {}
if fridge == "true": 
    k["fridge"] = True
if toilet == "true": 
    k["toilet"] = True
if side_window == "true": 
    k["sun_side_window"] = True
q = queryset.filter(**k)