一、入门使用
1、安装
pip install django-filter
2、配置
# settings.py
INSTALLED_APPS = [
...
'django_filters', # 过滤器
...
]
REST_FRAMEWORK = {
...
# 全局 过滤配置
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
...
}
3、视图中使用
class UserInfoView(GenericAPIView, ListModelMixin):
queryset = UserInfo.objects.all()
serializer_class = UserInfoSerializer
# 过滤器
filter_backends = [DjangoFilterBackend]
filterset_fields = ['id', 'username', "is_delete"]
def get(self, request):
return self.list(request=request)
4、访问 (默认是 精准 匹配)
http://127.0.0.1:9989/vueshop/user/?username=test
http://127.0.0.1:9989/vueshop/user/?username=test&id=xx&is_delete=
响应:
{
"page": 1,
"count": 1,
"totals": 1,
"lists": [
{
"id": 2,
"username": "test",
"mobile": "1985622634",
"email": "test@aa.com",
"is_staff": false,
"is_active": false
}
]
}
二、高级使用
背景:
当默认精准匹配无法满足,需要模糊匹配,大于等于小于等其他需求时,可以自定义过滤器类。
1、模型类
from django.db import models
# Create your models here.
class Students(models.Model):
name = models.CharField(max_length=20)
age = models.IntegerField()
sex = models.BooleanField(default=False)
join_time = models.DateTimeField(auto_now_add=True)
modify_time = models.DateTimeField(auto_now=True)
def __str__(self):
return f'{self.name} 的年龄是 {self.age}'
2、自定义一个过滤器类
from django_filters import rest_framework as filters
from testDRF.models import Students
class DiyFilter(filters.FilterSet):
# 名称包含传入的值
s_name = filters.CharFilter(field_name='name',lookup_expr='icontains')
# 年纪大于传入的值
s_age = filters.NumberFilter(field_name='age',lookup_expr='gt')
# 创建时间等于 传入的年的值
s_join_time = filters.NumberFilter(field_name='join_time',lookup_expr='year')
# 创建时间大于 传入的年的值
s_join_time_gt = filters.NumberFilter(field_name='join_time',lookup_expr='year__gt')
# 创建时间等于 传入的月的值
s_time_month = filters.NumberFilter(field_name='join_time',lookup_expr='month')
class Meta:
# 模型类名
model = Students
# 可以过滤的字段
fields = ['name', 'age']
上面的请求参数格式,按顺序展示:如下:
GET /testDRF/diyfilter/?name=test&age=&s_name=&s_age=&s_join_time=&s_join_time_gt=&s_time_month=
GET /testDRF/diyfilter/?name=&age=21&s_name=&s_age=&s_join_time=&s_join_time_gt=&s_time_month=
GET /testDRF/diyfilter/?name=&age=&s_name=te&s_age=&s_join_time=&s_join_time_gt=&s_time_month=
GET /testDRF/diyfilter/?name=&age=&s_name=&s_age=12&s_join_time=&s_join_time_gt=&s_time_month=
GET /testDRF/diyfilter/?name=&age=&s_name=&s_age=&s_join_time=2022&s_join_time_gt=&s_time_month=
GET /testDRF/diyfilter/?name=&age=&s_name=&s_age=&s_join_time=&s_join_time_gt=2021&s_time_month=
GET /testDRF/diyfilter/?name=&age=&s_name=&s_age=&s_join_time=&s_join_time_gt=&s_time_month=05
- 参数说明:
field_name: 过滤字段名,一般应该对应模型中字段名
lookup_expr: 查询时所要进行的操作,和ORM中运算符一致
- Meta字段说明
model: 引用的模型,不是字符串
fields:指明过滤字段,可以是列表,默认是判等;也可以字典,字典可以自定义操作
exclude = ['password'] 排除字段,不允许使用列表中字典进行过滤
3、在视图中配置
class DiyFilterView(GenericAPIView, ListModelMixin):
queryset = Students.objects.all()
serializer_class = StudentSerializer
# 过滤器
filter_backends = [DjangoFilterBackend]
# 自定义的过滤器类
filterset_class = DiyFilter
def get(self, request):
return self.list(request=request)
4、自定义过滤器类的另一种写法
from django_filters import rest_framework as filters
from testDRF.models import Students
class DiyFilter(filters.FilterSet):
...
class Meta:
# 模型类名
model = Students
# 可以过滤的字段
# fields = ['name', 'age']
# 另一种写法,放字典里控制
fields = {
'name': ['exact','icontains'],
"age": ['exact', 'gte', 'lte'],
}
三、搜索过滤器SearchFilter
SearchFilter过滤器来帮助我们快速指明数据按照指定字段进行搜索。
1、配置
全局配置在settings配置,不在讲述。这里直接在视图里定义
class DiyFilterView(GenericAPIView, ListModelMixin):
queryset = Students.objects.all()
serializer_class = StudentSerializer
pagination_class = None
# 过滤器
filter_backends = [SearchFilter] # 配置过滤器类
search_fields = ['name', 'age'] # 配置搜索字段
def get(self, request):
return self.list(request=request)
2、使用
GET /testDRF/diyfilter/?search=12
然后会根据search的值,去配置的字段 name 或者 age,只要有一个模糊匹配到search的值,就满足。
四、排序
from rest_framework import filters
class DiyFilterView(GenericAPIView, ListModelMixin):
queryset = Students.objects.all()
serializer_class = StudentSerializer
pagination_class = None
# 排序
filter_backends = [filters.OrderingFilter]
# 排序字段
ordering_fields = ['name', 'age']
def get(self, request):
return self.list(request=request)
GET /testDRF/diyfilter/?ordering=age,-name
GET /testDRF/diyfilter/?ordering=age
负-大到小,正-小到大