Django RQL过滤
django-rql的Python项目详细描述
Django RQL公司
django-rql
是一个Django应用程序,它为您的web应用程序实现RQL过滤器后端。在
RQL公司
RQL(资源查询语言)是为现代应用程序开发而设计的。它是为web构建的,为NoSQL做好了准备,并且具有高度的可扩展性,语法简单。 这是一种查询语言,快速方便的数据库交互。RQL是为在url中请求对象样式的数据结构而设计的。在
注意事项
解析是用Lark(cheatsheet)完成的。 当前的解析算法是使用标准lexer的LALR(1)。在
当前支持的运算符
- 比较(eq、ne、gt、ge、lt、le、like、ilike、搜索)
- 列表(输入、输出)
- 逻辑(and,or,not)
- 常量(null(),empty())
- 订货(订货)
- 选择(Select)
文件
完整的文档可在https://django-rql.readthedocs.org上找到。在
示例
fromdj_rql.constantsimportFilterLookupsfromdj_rql.filter_clsimportRQLFilterClass,RQL_NULLclassModelFilterClass(RQLFilterClass):""" MODEL - Django ORM model FILTERS - List of filters EXTENDED_SEARCH_ORM_ROUTES - List of additional Django ORM fields for search DISTINCT - Boolean flag, that specifies if queryset must always be DISTINCT SELECT - Boolean flag, that specifies if Filter Class supports select operations and queryset optimizations OPENAPI_SPECIFICATION - Python class that renders OpenAPI specification Filters can be set in two ways: 1) string (default settings are calculated from ORM) 2) dict (overriding settings for specific cases) Filter Dict Structure { 'filter': str # or 'namespace': str 'source': str # or 'sources': iterable # or 'custom': bool # or 'dynamic': bool 'field': obj 'lookups': set 'qs': obj 'use_repr': bool # can't be used in namespaces 'ordering': bool # can't be true if 'use_repr=True' 'search': bool # can't be true if 'use_repr=True' 'hidden': bool } """MODEL=ModelFILTERS=['id',{# `null_values` can be set to override ORM is_null behaviour# RQL_NULL is the default value if NULL lookup is supported by field'filter':'title','null_values':{RQL_NULL,'NULL_ID'},'ordering':False,},{# `ordering` can be set to True, if filter must support ordering (sorting)# `ordering` can't be applied to non-db fields'filter':'status','ordering':True,},{# `search` must be set to True for filter to be used in searching# `search` must be applied only to text db-fields, which have ilike lookup'filter':'author__email','search':True,},{# `source` must be set when filter name doesn't match ORM path'filter':'name','source':'author__name',},{# `namespace` is useful for API consistency, when dealing with related models'namespace':'author','filters':['id','name'],# will be converted to `author.id` and `author.name`},{# `distinct` needs to be setup for filters that require QS to work in DISTINCT mode# `openapi` configuration is automatically collected by OpenAPI autogenerator'filter':'published.at','source':'published_at','distinct':True,'openapi':{'required':True,'deprecated':True,'description':'Good description','hidden':False,# can be set to avoid collecting by autogenerator# type and format are collected automatically and shouldn't be setup, in general'type':'string','format':'date',},},{# `use_repr` flag is used to filter by choice representations'filter':'rating.blog','source':'blog_rating','use_repr':True,},{# `hidden` flag is used to set default select behaviour for associated field'filter':'rating.blog_int','source':'blog_rating','use_repr':False,'ordering':True,'hidden':True,},{# We can change default lookups for a certain filter'filter':'amazon_rating','lookups':{FilterLookups.GE,FilterLookups.LT},},{# Sometimes it's needed to filter by several sources at once (distinct is always True).# F.e. this could be helpful for searching.'filter':'d_id','sources':{'id','author__id'},'ordering':True,},{# Some fields may have no DB representation or non-typical ORM filtering# `custom` option must be set to True for such fields'filter':'custom_filter','custom':True,'lookups':{FilterLookups.EQ,FilterLookups.IN,FilterLookups.I_LIKE},'ordering':True,'search':True,'custom_data':[1],}]fromdj_rql.drf.backendimportRQLFilterBackendfromdj_rql.drf.paginationsimportRQLContentRangeLimitOffsetPaginationclassDRFViewSet(mixins.ListModelMixin,GenericViewSet):queryset=MODEL.objects.all()serializer_class=ModelSerializerrql_filter_class=ModelFilterClasspagination_class=RQLContentRangeLimitOffsetPaginationfilter_backends=(RQLFilterBackend,)
注释
- 带有空格或特殊字符的值,如“,”需要有“”或“”
- 支持的日期格式为ISO8601:2019-02-12
- 支持的日期时间格式为ISO8601:2019-02-12T10:02:00/2019-02-12T10:02Z/2019-02-12T10:02:00+03:00
- 添加了对来自Django Model Utilities的Choices()字段的支持
Django Rest框架扩展
- 分页(限制、偏移)
- 支持从基本模型字段(如CharField())继承的任何深度的自定义字段。在
- 后端
DjangoFiltersRQLFilterBackend
,自动将Django-Filters查询转换为RQL查询。在 - OpenAPI文档是为过滤器类自动生成的。在
最佳实践
- 使用
dj_rql.utils.assert_filter_cls
测试API视图筛选器。如果映射是正确的,并且没有定制的过滤逻辑,那么实际上可以保证过滤将正确工作。在 - 优先使用
custom=True
和RQLFilterClass.build_q_for_custom_filter
重写而不是重写{}。在 - 自定义筛选器可能支持使用
build_name_for_custom_ordering
排序(ordering=True
)。在
发展
- Python 3.5+
- 安装依赖项
requirements/dev.txt
和requirements/extra.txt
测试
- Python 3.6+
- 安装依赖项
requirements/test.txt
export PYTHONPATH=/your/path/to/django-rql/
检查代码样式:flake8
运行测试:pytest
测试报告在tests/reports
中生成。在
out.xml
-JUnit测试结果coverage.xml
-覆盖率xml结果
要生成HTML覆盖率报告,请使用:
--cov-report html:tests/reports/cov_html
- 项目
标签: