如何在过滤器中添加if语句?

2024-10-02 04:30:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我有4个参数:城市,省,类型,方向,当参数不为空时我想在过滤器中使用它,当它为空时,不要将它设置为过滤关键字。在

我使用的当前代码部分如下:

if (direction == '') & (strtype == '') & (city == '') & (province == ''):
    queryset = address.objects.filter(addline__startswith=keyword)[:10]
    if not queryset.exists():
        queryset = address.objects.filter(strname__startswith=keyword)[:10]
        return queryset
    else:
        return queryset

if (direction != '') & (strtype == '') & (city == '') & (province == ''):
    queryset = address.objects.filter(addline__startswith=keyword, 
                                      strdir=direction)[:10]
    if not queryset.exists():
        queryset = address.objects.filter(strname__startswith=keyword, 
                                          strdir=direction)[:10]
        return queryset
    else:
        return queryset

有16种可能性,这意味着我需要写16个if语句!这是太多的代码和不光彩,有没有一个简洁的解决方案?在


Tags: 代码city参数returnifobjectsaddressfilter
2条回答

There are 16 posibilities, it means i need to write 16 if statements!

不!如果这些参数的作用或多或少独立,则不是这样。例如,我们可以先抽象出普通逻辑:

def add_custom_filters(qs, direction, strtype, city, province):
    if direction:
        qs = qs.filter(strdir=direction)
    if strtype:
        qs = qs.filter(strype=strtype)
    if city:
        qs = qs.filter(strcity=city)
    if privince:
        qs = qs.filter(strprov=privince)
    return qs

(可能需要修改)

所以现在我们可以使用这个逻辑,比如:

^{pr2}$

因此,我们只需要四个if的情况,并且我们在两次尝试的方法中重用这个函数。在

由于过滤如果不为真是一种常见模式,我们可以将其封装在一个助手函数中:

def filter_if_truthfull(qs, **kwargs):
    retrurn qs.filter(**{k: v for k, v in kwargs.items() if v})

然后我们可以像这样使用它:

queryset = address.objects.filter(addline__startswith=keyword)
queryset = filter_if_truthfull(queryset, strdir=direction, strtype=strtype, strcity=city, strprov=province)[:10]
if not queryset:
    queryset = address.objects.filter(strname__startswith=keyword)
    queryset = filter_if_truthfull(queryset, strdir=direction, strtype=strtype, strcity=city, strprov=province)[:10]
return queryset

这允许我们添加任意数量的名为的筛选条件,这些条件只在值为truthiness true时应用(对于字符串,如果字符串不是空的,如果它是None,它不是字符串,但也不考虑这些筛选器)。在

无论如何,如果您要使用QuerySet的结果,最好检查if queryset,因为这将执行一个查询,该查询也会将元素加载到查询集中,而.exists()将使用EXISTS查询进行查询,如果您想稍后处理这些元素,则需要执行额外的查询以在内存中获取它们。在

您可以构建一个字典,然后使用双星语法f(**kwargs)将其作为关键字参数传递:

conds = {}
if direction != '': conds["strdir"] = direction
if strtype != '': conds["strtype"] = strtype
if province != '': conds["province"] = province
if city != '': conds["city"] = city
queryset = address.objects.filter(addline__startswith=keyword, 
                                  **conds)[:10]
if not queryset.exists():
    queryset = address.objects.filter(strname__startswith=keyword, 
                                      **conds)[:10]

相关问题 更多 >

    热门问题