2016-08-16 57 views
1

我在Python中使用了幾個過濾器中的以下代碼。然後我有一個循環,每個都調用.filter。但是,當你調用多個過濾器時,這些都是與。我怎樣才能改變它,以便對過濾器的多個調用進行「或」運算。問題出在我的代碼的「其他」部分。如何在Python中使用多個過濾器調用

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'])))) 

回答

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)) 
+0

這是非常有用的代碼,可以幫助我學習更靈活的方法。 – Ray

0

剛建立的過濾器列表和or_他們在最後:

exprs = [] 
for filter_ in filters: 
    exprs.append(field.ilike(...)) 
organizations_products = organizations_products.filter(or_(*exprs)) 

順便說一句,實現搜索這個樣子去表現明智的一個可怕的方式(除非你在PostgreSQL上並且有一個trigram索引,在這種情況下忽略這個)。使用數據庫的全文搜索功能可以更好地服務您。

相關問題