跳转到主要内容

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 (55.6 kB 查看哈希值)

上传时间 源代码

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面