Python模块,为任何项目列表添加ORM风格过滤支持
项目描述
什么
QueryableList 允许您“过滤”各种类型的项目列表,通过将繁琐的循环替换为简单的链式调用,简化代码。
它使用Django、Flask和IndexedRedis等一些ORM共有的接口。
您可以在数据列表上执行单个过滤,也可以构建查询并在任意数量的数据集上执行该查询。
QueryableList 还实现了列表的布尔逻辑运算符(AND、OR、XOR),可以简化您的代码。
它取代了什么模式?
用于深入数据的常量循环/获取器。如果您正在过滤数据、按标准显示数据等,您的代码将充满这些。
QueryableList 简化了通用过滤模式的通用性。
之前
def getOlderThan(people, minAge)
ret = []
for person in people
if person.age and person.age > minAge
ret.append(person)
return ret
…
people = getAllPeople() # 获取你的数据
oldEnoughToRide = getOlderThan(people, 13)
notOldEnough = [person for person in people if person not in oldEnoughToRide]
之后
people = QueryableListObjs( getAllPeople() ) # 将数据转换为 QueryableList
oldEnoughToRide = people.filter(age__gt=13)
notOldEnough = people ^ oldEnoughToRide # 过滤列表与父列表的异或是对过滤条件的非操作
没有函数、没有循环和列表推导可以变得非常混乱或不可能,当应用大量的复杂过滤器时。
上面的示例显示了列表的一次性过滤。您还可以构建可重用查询,并根据条件或通过在不同函数中传递查询来添加不同的标准。有关更多信息,请参阅下面的“构建可重用查询”部分。
如何?
类型
通过列表类型的扩展类之一执行一次性过滤
QueryableListObjs - 假设每个项扩展了对象[或实现了 __getattribute__]。
QueryableListDicts - 假设每个项是字典[或实现了 __getitem__]。
QueryableListMixed - 可以包含字典类似项或对象类似项的 QueryableList。(这比直接使用 QueryableListObjs 或 QueryableListDicts 慢一些,但如果你需要混合,或需要支持任一类型,则使用它。)
这些列表中的项不需要是同一类型。如果过滤对象中缺少任何字段,则将分配一个值为“None”的值用于过滤。
过滤方法
您可以通过以下方法之一过滤这些对象中的数据
filterAnd - 返回一个 QueryableList,其中每个项都符合提供的所有标准。
filter - filterAnd 的别名
filterOr - 返回一个 QueryableList,其中每个项都符合提供的任何标准。
customFilter - 接受 lambda 或函数作为参数。将列表中的每个元素传递到该函数中,如果它返回 True,则保留该元素。
QueryableList 类型支持所有列表操作,并返回相同的 QueryableList 类型,因此您可以进行链式操作。
此外,您可以使用 ADD(+)、SUB(-)、AND(&)、OR(|) 和 XOR(^) 运算符对其他 QueryableLists 进行操作,作为另一种强大的过滤方法。
您通过传递 $fieldName__$operation 的参数指定过滤操作。
示例:e.x. results = objs.filter(name__ne='Tim') # 获取所有 'name' 字段不等于 'Tim' 的对象
有关所有可用操作的更多信息,请参阅下面的“操作”部分。
其他方法
QueryableList 集合有几种其他方法,以便尽可能与服务器端过滤 ORMs 兼容。
这允许您使用相同的函数,无论您是在服务器端还是客户端过滤。
count - 返回此集合中的项目数(与 len(..) 相同)
all - 返回此集合的副本,具有相同元素但新的集合
构建可重用查询
您可以使用 QueryBuilder 类构建一个可重用查询,该查询由多个过滤链(AND 或 OR)组成。
QueryBuilder 类存储一个“链”的过滤器,按顺序应用。链中的每个链接都包含一个过滤器类型(AND 或 OR)以及过滤器本身(与 QueryableList 上的过滤方法相同)。
使用 addFilter(filterType, ..filters..) 方法向链中添加链接。
要执行查询,请调用 execute(lst) 方法,其中“lst”是您的项目列表。您可以在任意数量的数据集上多次执行查询。
使用 copy 方法创建当前过滤器集合的副本。
如果您事先知道类型,可以在调用 execute 时传递 QueryableListObjs 或 QueryableListDicts 以略微加快访问速度;否则将使用 QueryableListMixed(支持字典和对象风格访问)。
示例
myQuery = QueryBuilder()
myQuery.addFilter(age__gt=21) # 年龄必须大于21
myQuery.addFilter(‘OR’, job__ieq=’Manager’, numSubordinates__gt=0) # 是经理,或拥有超过0名下属
managerPartyCompany1 = myQuery.execute(company1Persons) # 从所有 company1Persons 中筛选出符合上述条件的员工
managerPartyCompany2 = myQuery.execute(company2Persons) # 使用相同的过滤器将相同的查询应用于 company2Persons
扩展 QueryableList 以适用于您的数据集
QueryableList 的一个强大之处在于它易于扩展。
通常,您不需要这样做,因为 QueryableListDicts 或 QueryableListObjs 将满足您的需求。
但有时,您可能有比属性和匹配更复杂的需求。
在这种情况下,您可以扩展 QueryableList.QueryableListBase 来创建自己的 QueryableList 类型。
您只需实现一个方法,
@staticmethod
def _get_item_value(item, fieldName)
“item”将是您的集合中的一个项目,而“fieldName”是要查询的字段。
例如,假设您有一系列对象,“Job”,它们包含一些属性和一个“queue”。
您希望能够根据对象上的属性及其队列的各种特殊属性(如大小、项目ID等)进行筛选。
您可以像这样实现
class MyJobCollection(QueryableList.QueryableListBase)
@staticmethod
def _get_item_value(item, fieldName)
if fieldName == ‘queueSize’
# queueSize 是队列中的项目数量
return len(item.queue)
elif fieldName == ‘queueItemIds’
# queueItemIds 是项目队列中的ID列表,
# 因此“包含”查询可以检查ID是否在项目队列中
return [qi.id for qi in item.queue]
elif hasattr(item, fieldName)
# 否则,如果这是项目上的属性,则返回它的值
if fieldName == ‘queue’
raise KeyError(‘不能直接查询队列。请尝试 queueSize 或 queueItemIds。’)
return getattr(item, fieldName)
else
raise KeyError(‘无效属性 “%s” 在 %s’ %(fieldName, item.__class__.__name__))
init 方法接受一个项目列表(它包含所有列表的方法,如 .append),因此您可以像这样创建它
myJob1 = MyQueue(…)
myJob2 = MyQueue(…)
myJobs = MyQueueCollection([myJob1, myJob2])
然后像这样使用它
largeJobs = myJobs.filter(queueSize__gt=10)
所以,仅通过实现该方法,您现在就拥有了 QueryableList 提供的所有强大的筛选功能!
操作
eq - 测试相等(=运算符)
ieq - 测试相等,忽略大小写(必须是字符串,或者至少实现 .lower() 方法)
ne - 测试不等(!=运算符)
ine - 测试不等,忽略大小写(必须是字符串,或者至少实现 .lower() 方法)
lt - 项目字段的值必须小于提供的值
lte - 项目字段的值必须小于或等于提供的值
gt - 项目字段的值必须大于提供的值
gte - 项目字段的值必须大于或等于提供的值
isnull - 提供的值必须是 True/False。如果为 True,则项目的字段值必须为 None,否则不能为 None。
is - 测试身份相等(is运算符)
isnot - 测试身份不等(is not运算符)
in - 测试项目的字段值是否包含在提供的项目列表中
notin - 测试项目的字段值是否不在提供的项目列表中
contains - 测试项目的字段值是否包含提供的值(使用“in”)
icontains - 不区分大小写的“contains”
notcontains - 测试项目的字段值是否不包含提供的值(使用“not in”)
icontains - 不区分大小写的“notcontains”
containsAny - 测试项目的字段值是否包含提供的列表中的任何项目(使用“in”)
notcontainsAny - 测试项目的字段值是否不包含提供的列表中的任何项目(使用“not in”)
splitcontains - 接收一个元组,(splitBy
,containsThis )。用于表示列表的字符串。字段将被第一个参数“splitBy”分割,并检查结果是否包含第二个参数“containsThis”匹配的项目。例如:item__splitcontains=(' ','someValue') splitnotcontains - 接收一个元组,(splitBy
,containsThis )。用于表示列表的字符串。字段将被第一个参数“splitBy”分割,并检查结果是否不包含第二个参数“containsThis”匹配的项目。 splitcontainsAny - 接收一个元组,(splitBy
,possibleMatches - >)。用于表示列表的字符串。字段将被第一个参数“splitBy”分割,并检查结果是否包含提供的列表中的任何项目。
splitnotcontainsAny - 接收一个元组,(splitBy
,possibleMatches - >)。用于表示列表的字符串。字段将被第一个参数“splitBy”分割,并检查结果是否不包含提供的列表中的任何项目。
customMatch - 接收一个lambda或函数,它将给定字段的值传递给函数。如果它返回True,则元素匹配,否则不匹配。
完整PyDoc文档
Pydoc文档可以在以下位置找到:[http://htmlpreview.github.io/?https://github.com/kata198/QueryableList/blob/master/doc/QueryableList.html](http://htmlpreview.github.io/?https://github.com/kata198/QueryableList/blob/master/doc/QueryableList.html)?vers=4
项目详情
QueryableList-3.1.0.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 8891dccbadc69a35f5944e1826d8f8db224522aa3af913e301a7a448f5b411e9 |
|
MD5 | e9be982545ecda0d15f2b3ff718d758f |
|
BLAKE2b-256 | 59cdff38fb62fc81def97f50a98fc4bdbbe258351b5be8be6a6b69fec7a25c81 |