过滤器DjangoFilterBackend
第三方过滤器DjangoFilterBackend
安装/配置:
pip install django-filter 注册app INSTALLED_APPS = [ ... 'django_filters', ... ]
视图配置和应用(1)
需求:以id和username参数值为条件,返回数据。默认只支持等于筛选条件;
例如:http://127.0.0.1:8003/app01/api/user/five/?username=admin12&id=6
from rest_framework.viewsets import ModelViewSet from django_filters.rest_framework import DjangoFilterBackend from apps.api import models class UsernameModelSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" class UserView(ModelViewSet): filter_backends = [DjangoFilterBackend,] filterset_fields = ["id","username"] # 根据定义字段做等于筛选,对应数据库中字段 queryset = models.UserInfo.objects.all() serializer_class = UsernameModelSerializer
扩展DjangoFilterBackend支持更多筛选条件
视图配置和应用(2)
需求:根据用户名、>=id来筛选数据
views.py
from django_filters.rest_framework import DjangoFilterBackend from django_filters import FilterSet,filters # 扩展DjangoFilterBackend class MyFilterSet(FilterSet): creator = filters.CharFilter(field_name="creator__username") # fields_name参数值对应数据库字段 min_id = filters.CharFilter(field_name="id", lookup_expr="gte") # lookup_expr参数定义筛选条件 class Meta: model = models.Blog fields = ["creator", "min_id"] # 自定义筛选参数名 class BlogFilterView(ModelViewSet): filter_backends = [DjangoFilterBackend, ] filterset_class = MyFilterSet # 自定义类来扩展筛选规则 queryset = models.Blog.objects.all() serializer_class = BlogModelSerializers
实例:获取id>=2&username=admin1数据:http://127.0.0.1:8001/api/app02/blog/filter/?min_id=2&username=admin1
视图配置和应用(实例3)
not筛选条件,返回username不等于admin1用户信息
class MyFilterSet(FilterSet): username = filters.CharFilter(field_name="creator__username",lookup_expr="exact",exclude=True) # not(不等于) username=admin min_id = filters.CharFilter(field_name="id", lookup_expr="gte") # lookup_expr参数定义筛选条件 class Meta: model = models.Blog fields = ["username", "min_id"] # 自定义筛选参数名 class BlogFilterView(ModelViewSet): filter_backends = [DjangoFilterBackend, ] filterset_class = MyFilterSet # 自定义类来扩展筛选规则 queryset = models.Blog.objects.all() serializer_class = BlogModelSerializers
视图配置和应用(实例4)
包含筛选内容,博客标题中包含筛选值
class MyFilterSet(FilterSet): title = filters.CharFilter(field_name="title",lookup_expr="contains") # 标题内容包含筛选值 min_id = filters.CharFilter(field_name="id", lookup_expr="gte") # lookup_expr参数定义筛选条件 class Meta: model = models.Blog fields = ["title", "min_id"] # 自定义筛选参数名 class BlogFilterView(ModelViewSet): filter_backends = [DjangoFilterBackend, ] filterset_class = MyFilterSet # 自定义类来扩展筛选规则 queryset = models.Blog.objects.all() serializer_class = BlogModelSerializers
http://127.0.0.1:8001/api/app02/blog/filter/?title=云计算
常见实例:
class MyFilterSet(FilterSet): # /api/users/?min_id=2 -> id>=2 min_id = filters.NumberFilter(field_name='id', lookup_expr='gte') # /api/users/?name=wupeiqi -> not ( username=wupeiqi ) name = filters.CharFilter(field_name="username", lookup_expr="exact", exclude=True) # /api/users/?depart=xx -> depart__title like %xx% depart = filters.CharFilter(field_name="depart__title", lookup_expr="contains") # /api/users/?token=true -> "token" IS NULL # /api/users/?token=false -> "token" IS NOT NULL token = filters.BooleanFilter(field_name="token", lookup_expr="isnull") # /api/users/?email=xx -> email like xx% email = filters.CharFilter(field_name="email", lookup_expr="startswith") # /api/users/?level=2&level=1 -> "level" = 1 OR "level" = 2(必须的是存在的数据,否则报错-->内部有校验机制) # level = filters.AllValuesMultipleFilter(field_name="level", lookup_expr="exact") level = filters.MultipleChoiceFilter(field_name="level", lookup_expr="exact", choices=models.UserInfo.level_choices) # /api/users/?age=18,20 -> age in [18,20] age = filters.BaseInFilter(field_name='age', lookup_expr="in") # /api/users/?range_id_max=10&range_id_min=1 -> id BETWEEN 1 AND 10 range_id = filters.NumericRangeFilter(field_name='id', lookup_expr='range') # /api/users/?ordering=id -> order by id asc # /api/users/?ordering=-id -> order by id desc # /api/users/?ordering=age -> order by age asc # /api/users/?ordering=-age -> order by age desc ordering = filters.OrderingFilter(fields=["id", "age"]) # /api/users/?size=1 -> limit 1(自定义搜索) size = filters.CharFilter(method='filter_size', distinct=False, required=False) class Meta: model = models.UserInfo fields = ["id", "min_id", "name", "depart", "email", "level", "age", 'range_id', "size", "ordering"] def filter_size(self, queryset, name, value): int_value = int(value) return queryset[0:int_value] class UserView(ModelViewSet): filter_backends = [DjangoFilterBackend, ] filterset_class = MyFilterSet queryset = models.UserInfo.objects.all() serializer_class = UserModelSerializer
lookup_expr常见选择
'exact': _(''), 'iexact': _(''), 'contains': _('contains'), 'icontains': _('contains'), 'startswith': _('starts with'), 'istartswith': _('starts with'), 'endswith': _('ends with'), 'iendswith': _('ends with'), 'gt': _('is greater than'), 'gte': _('is greater than or equal to'), 'lt': _('is less than'), 'lte': _('is less than or equal to'), 'in': _('is in'), 'range': _('is in range'), 'isnull': _(''),
全局配置和应用
REST_FRAMEWORK = { 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend',] }