类似于Django Q对象构建的谓词类,用于测试新模型或修改后的模型是否会与查询匹配
项目描述
注意
2022-04-27: 此库目前未维护,因为我不再使用Django。如果有任何兴趣,我仍然愿意审查拉取请求并考虑添加维护者。- @lucaswiman
django-predicate
django-predicate提供了一个类似于Q对象的P对象,用于辅助回答:“此模型实例是否会被查询包含”,但不运行查询甚至不保存对象。
快速入门
安装django-predicate
pip install django-predicate
然后像使用Q对象一样使用P对象
from predicate import P
p = P(some_field__startswith="hello", age__gt=20)
然后您可以调用带有模型实例的eval方法来检查它是否通过条件
model_instance = MyModel(some_field="hello there", age=21)
other_model_instance = MyModel(some_field="hello there", age=10)
p.eval(model_instance)
>>> True
p.eval(other_model_instance)
>>> False
或者您可以使用Python的in运算符。
model_instance in p
>>> True
尽管谓词不是一个真正的容器类 - 它可以用作(并且被设计为)一个满足某些条件的虚拟“集合”。
与Q对象一样,P对象也可以通过&和|进行组合,以形成更复杂的逻辑分组。
实际上,P对象是Q对象的子类,因此可以在查询集过滤器语句中使用它们
qs = MyModel.objects.filter(p)
P对象还支持类似于QuerySet的过滤操作,可以应用于任意可迭代对象:P.get(iterable),P.filter(iterable)和P.exclude(iterable)
model_instance = MyModel(some_field="hello there", age=21)
other_model_instance = MyModel(some_field="hello there", age=10)
p.filter([model_instance, other_model_instance]) == [model_instance]
>>> True
p.get([model_instance, other_model_instance]) == model_instance
>>> True
p.exclude([model_instance, other_model_instance]) == [other_model_instance]
>>> True
如果您遇到需要根据相同条件使用查询集和谓词的情况,最好从谓词开始。由于查询集假设SQL上下文,将它们反向工程回谓词并不简单。然而,如上所示,基于谓词创建查询集非常简单。
开发
这些说明假设您已安装Postgres,并安装并激活了所有引用的Python版本,例如使用Pyenv。
要本地运行测试,请执行以下操作
克隆此存储库。
使用postgres -D ~/postgres在后台启动Postgres以进行Postgres测试。
激活此存储库中使用的所有测试Python版本:pyenv local 3.6 3.7 3.10。
(可选)创建一个虚拟环境并激活它:python -m venv .venv,source .venv/bin/activate。
(可选)升级pip以防止平台问题:pip install --upgrade pip
安装Tox以运行测试:pip install tox。
通过不带参数的tox命令运行所有测试。
变更日志
2.0.1
增加了对Python 3.7和3.10以及Django 2.2、3.2和4.1的支持(有关兼容的Python/Django版本组合,请参阅tox.ini)。
将测试运行器从Nose转换为Pytest。
重大变更 移除了对Python 2.7、Python 3.5和Django 1.9的支持。
2.0.0(未发布)
此版本已推送到Master,但未推送到PyPI。
在README中添加了弃用警告。
添加了Travis CI配置。
重大变更 移除了对Django 1.7和1.8的支持。
1.4.0
此版本及以下版本未包含在此变更日志中。