我在Python中有以下代码,它接受了几个过滤器。然后我有一个循环,在每个上面调用.filter。但是,当您调用多个过滤器时,它们都是AND。如何更改它以便多次调用过滤器进行OR运算。问题出在" else"我的代码的一部分。
for filter_ in filters:
field_models = {'type': ProductType, 'category': ProductCategory}
if filter_['field'] in field_models:
model = field_models[filter_['field']]
organizations_products = organizations_products.join(model).filter(or_(
model.code.ilike('%{}%'.format(escape_like(filter_['value']))),
model.description.ilike('%{}%'.format(escape_like(filter_['value'])))
))
else:
field = getattr(Product, filter_['field'])
organizations_products = organizations_products.filter(
field.ilike('%{}%'.format(escape_like(filter_['value']))))
答案 0 :(得分:1)
解决方案分为两部分。首先,我们必须构造from
子句,然后构造where
子句。
def get_joined_stmt(filters, stmt):
if 'type' in filters.keys():
stmt = stmt.join(ProductType)
if 'category' in filters.keys():
stmt = stmt.join(ProductCategory)
return stmt
def get_exprs(field, value):
def _ilike_expr(x): return '%{}%'.format(escape_like(x))
model_dict = {'type': ProductType, 'category': ProductCategory}
model = model_dict[field]
stmt = organizations_products.join(model)
try:
return [model.code.ilike(_ilike_expr(value)),
model.description.ilike(_ilike_expr(value))]
except KeyError:
return [getattr(Product, field).ilike(_ilike_expr(value))]
organizations_products = get_joined_stmt(filters, organizations_products)
where_exprs = []
for filter_ in filters.items():
where_exprs.extend(get_exprs(**filter_))
organizations_products = organizations_products.filter(or_(*where_exprs))
答案 1 :(得分:0)
只需在最后建立一个过滤器列表并or_
:
exprs = []
for filter_ in filters:
exprs.append(field.ilike(...))
organizations_products = organizations_products.filter(or_(*exprs))
顺便说一句,实现这样的搜索是一种可靠的性能方式(除非你在PostgreSQL上并且有一个三元组索引,在这种情况下忽略它)。通过使用数据库的全文搜索功能,您可以获得更好的服务。