rest_framework.filters的简单替换
django-simplefilters的Python项目详细描述
django simplefilters
这是内置django rest framework filters包的替换。它提供了一种从url检索参数并使用它们来缩小queryset结果范围的简单方法。
与其他解决方案(即django-filter)的主要区别在于,我们不尝试处理每个情况,而实际的筛选留给用户实现。对于过滤库来说,这听起来可能有违直觉,但我们相信,在许多情况下,编写类似于
class EntryFilterSet(filters.FilterSet):
@filters.CharFilter(many=True)
def filter_status(self, queryset, values):
return queryset.filter(status__in=values)
尝试在筛选库文档中查找此特殊情况(多个值)。
安装
$ pip install django-simplefilters
用法
假设我们有一个具有以下属性的Entry
模型:
status_choices = ((c, c) for c in ['draft', 'published', 'archived'])
class Entry(models.Model):
title = models.CharField(max_length=64)
status = models.CharField(max_length=16, choices=status_choices)
modified_at = models.DateTimeField(auto_now=True)
我们希望允许所有者按其状态和修改日期筛选条目。
我们需要首先定义过滤器集:
# entries/filtersets.py
import simplefilters as filters
class Entry(filters.FilterSet):
@filters.CharFilter()
def filter_status(self, queryset, value):
return queryset.filter(status=value)
@filters.DateTimeFilter()
def filter_modified_at_min(self, queryset, ts):
return queryset.filter(modified_at__gte=ts)
@filters.DateTimeFilter()
def filter_modified_at_max(self, queryset, ts):
return queryset.filter(modified_at__lte=ts)
大多数情况下,这应该是不言而喻的,但是重要的一点是我们如何表示url param。这与序列化程序中的验证类似:参数名的前缀是filter_
字符串。因此,上面的代码定义了以下url参数的过滤器:status
、modified_at_min
和modified_at_max
。
然后将其挂接到相应的视图集类:
# entries/views.py
from . import filtersets
from . import models
import simplefilters as filters
class EntryViewSet(ModelViewSet):
serializer_class = ...
filter_backends = [filters.DjangoFilterBackend]
filter_class = filtersets.Entry
class Meta:
model = models.Entry
现在用户可以执行如下查询:
GET /entries?status=draft
GET /entries?modified_at_min=2018-03-30T14:00Z
etc.
支持的筛选器
根据定义,用户输入的任何查询参数都只是一个字符串。因此,CharFiled
是最简单和最基本的过滤器。但有时我们需要接受其他类型,即数字、时间戳或标志。
以下是可用筛选器的完整列表:
CharFilter
最基本的过滤器。这里没有什么新奇的事。
IntegerFilter
param被强制转换为整数。
FlagFilter
帕拉姆被铸成布尔。将被视为True
指示符的字符串(不区分大小写):yes
、y
、true
、t
和1
。类似地,这些将被视为False
:no
,n
,false
,f
和0
。
DateTimeFilter
param被强制转换为datetime
对象。
多个参数
有时我们想从url传递多个参数。在示例中,我们可能希望允许用户按多个状态值进行筛选,并执行如下操作:
GET /entries?status=draft&status=archived
为此,只需指示我们要在过滤器方法定义中使用many
值:
@filters.CharFilter(many)
def filter_status(self, queryset, values):
return queryset.filter(status__in=values)