假设我有一个带有多个可选过滤器的查询方法。我想要实现的是,如果我传递一些非None值来过滤参数然后做一个过滤器,如果过滤值是None,那么就忽略它。
def get_query_results(filter1=None, filter2=None, ...):
res = models.Item.query
if filter1 is not None:
res = res.filter(filter1=filter1)
if filter2 is not None:
res = res.filter(filter2=filter2)
....
return res.all()
我想要避免的是模式
if XXX:
res.filter(XXX=XXX)
我想知道是否有更优雅的方法来实现这一目标?
例如,将各种过滤器作为参数传递?
或许,当过滤器值为None时,我们可以做一些魔术来省略过滤器吗?
答案 0 :(得分:5)
完全等同于你所展示的代码:
def get_query_results(*filters):
res = models.Item.query
for i, filt in enumerate(filters, 1):
if filt is not None:
d = {'filter{}'.format(i): filt}
res = res.filter(**d)
return res.all()
我不太确定为什么你需要res.filter
的命名参数专门为filter1
,filter2
等,但是这个片段会在没有你重复模式的情况下完成可以理解地想要避免。
名称不实际上应该是filter1
,filter2
等,只要知道所需的名称就可以了:
NAMES = 'foo bar baz bat'.split()
def get_query_results(*filters):
res = models.Item.query
for name, filt in zip(NAMES, filters):
if filt is not None:
d = {name: filt}
res = res.filter(**d)
return res.all()
这种变体适用于这种情况。