我正在尝试创建一个存储
的程序并根据要求将其显示给用户。将为用户提供预定义的选择以供选择。像这样:
我的数据库表将是这样的:
现在,我正在尝试实现一个允许用户选择
的过滤器功能它会发出具有上述属性的所有Fruit Names
。但现在,我有一个额外的选项,“全部”。
假设我已经查询了所有水果的数据并将它们存储在字典中,如下所示:
myfruits = { 'apple':('fleshy','red','medium'),
'orange':('fleshy','orange','medium'),
'peanut':('dry','red','small'),...}
如何获取具有用户选择的三个属性的水果名称列表? (例如,如果用户选择“肉质”类型,“全部”颜色,“全部”尺寸 - 则应返回['apple','orange']
。)
我曾考虑使用if
语句,但随着属性数量的增加,我必须写出很多if
和else
行,我认为不是可行的。
答案 0 :(得分:10)
我在此处使用SQLAlchemy来处理数据库图层,使用as an ORM或仅使用generate the SQL expressions。
这可让您动态生成过滤器;您可以循环浏览过滤器,并且未将特定过滤器设置为“全部”,从而限制查询。
使用SQLAlchemy生成SQL表达式看起来像:
from sqlalchemy.sql import select
fruit_query = select([fruits])
for filtername in ui_filters:
filtervalue = obtain_filter_value_for(filtername)
if filtervalue != 'All':
fruit_query = fruit_query.where(filtername == filtervalue)
另一种方法是手动生成WHERE
子句:
query = 'SELECT * FROM fruits'
params = []
whereclauses = []
for filtername in ui_filters:
filtervalue = obtain_filter_value_for(filtername)
if filtervalue != 'All':
whereclauses.append('{} = ?'.format(filtername))
params.append(filtervalue)
if whereclauses:
query = '{} WHERE {}'.format(query, ' AND '.join(whereclauses))
cursor.execute(query, params)
但请注意,SQLAlchemy表达式引擎更灵活,更不容易出错。很快你就会想要添加更复杂的过滤器(在范围内搜索,文本搜索,在' OR'表达式中组合过滤器),SQLAlchemy可以生成表达式 lot 更简单,真的。
答案 1 :(得分:3)
如果您已经查询了所有数据,一种简单的方法就是使用filter
函数:
def predicate(fruit_type, fruit_color, fruit_size):
def _predicate(fruit):
if not fruit_type == 'All' and not fruit_type == fruit[1][0]:
return False
if not fruit_color == 'All' and not fruit_color == fruit[1][1]:
return False
if not fruit_size == 'All' and not fruit_size == fruit[1][2]:
return False
return True
return _predicate
query_type = 'All'
query_color = 'All'
query_size = 'All'
myfruits = {}
my_filtered_fruit = list(filter(predicate(query_type, query_color, query_size), myfruits.items()))
另一种方法是定义一个对象Predicate
,它有一个视图(过滤器的名称)和相关的过滤器函数:
class Predicate:
def __init__(self, predicate, view):
self.predicate = predicate
self.view = view
# Creation of the predicates :
all_color = Predicate(lambda fruit: True, 'All colors')
red_color = Predicate(lambda fruit: fruit[2] == 'red')
# ...
# Then you have to generate your select form. I don't remember exactly the PyQt4 doc but it's not the harder part.
predicates = getAllSelected() # I guess you know how to get this kind of function
myfruits = {}
my_filtered_fruits = myfruits.items()
for pred in predicates:
my_filtered_fruit = filter(lambda x: pred(x[1]), my_filtered_fruit)
my_filtered_fruit = list(my_filtered_fruit)