Sqlalchemy - элегантный способ борьбы с несколькими дополнительными фильтрами?
Предположим, что у меня есть метод запроса с серверными дополнительными фильтрами. Я хочу достичь: если я передаю некоторое значение 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?
Код, совершенно эквивалентный тому, который вы показали:
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()
Этот вариант будет работать в этом случае.