1.自定义filter
注意:只有在继承了GenericAPIView的视图类中才生效
代码
from app01.models import UserInfo from rest_framework import serializers from rest_framework.viewsets import GenericViewSet from rest_framework.viewsets import ModelViewSet from rest_framework.filters import BaseFilterBackend class UserModelSerializer(serializers.ModelSerializer): level_text = serializers.CharField(source='get_level_display', read_only=True) extra = serializers.SerializerMethodField(read_only=True) class Meta: model = UserInfo fields = ['username', 'age', 'email', 'level_text', 'extra'] def get_extra(self, obj): print(obj) return 666 class Filter1(BaseFilterBackend): def filter_queryset(self, request, queryset, view): age = request.query_params.get('age') if not age: return queryset return queryset.filter(age__gt=age) class Filter2(BaseFilterBackend): def filter_queryset(self, request, queryset, view): user_id = request.query_params.get('id') if not user_id: return queryset return queryset.filter(id__gt=user_id) class User(ModelViewSet): filter_backends = [Filter1, Filter2] queryset = UserInfo.objects.all() serializer_class = UserModelSerializer def perform_create(self, serializer): serializer.save(password="123")
源码分析
2.第三方filter
在drf开发中有一个常用的第三方过滤器:DjangoFilterBackend。
2.1 安装注册
安装
pip install django-filter
注册app
INSTALLED_APPS = [ ... 'django_filters', ]
全局配置和应用:
# settings.py 全局配置 REST_FRAMEWORK = { 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend',] }
2.2 简单使用
视图
1 from app01.models import UserInfo 2 from rest_framework import serializers 3 from rest_framework.viewsets import GenericViewSet 4 from rest_framework.mixins import ListModelMixin, \ 5 RetrieveModelMixin, \ 6 CreateModelMixin, \ 7 UpdateModelMixin, \ 8 DestroyModelMixin 9 from rest_framework.viewsets import ModelViewSet 10 from rest_framework.filters import BaseFilterBackend 11 from django_filters.rest_framework import DjangoFilterBackend 12 13 14 class UserModelSerializer(serializers.ModelSerializer): 15 level_text = serializers.CharField(source='get_level_display', read_only=True) 16 extra = serializers.SerializerMethodField(read_only=True) 17 18 class Meta: 19 model = UserInfo 20 fields = ['username', 'age', 'email', 'level_text', 'extra'] 21 22 def get_extra(self, obj): 23 print(obj) 24 return 666 25 return queryset.filter(id__gt=user_id) 26 27 28 class User(ModelViewSet): 29 filter_backends = [DjangoFilterBackend, ]
30 filterset_fields = ['id', 'age', 'email'] # 定义过滤的字段,是且的关系 31 queryset = UserInfo.objects.all() 32 serializer_class = UserModelSerializer 33 34 def perform_create(self, serializer): 35 serializer.save(password="123")
2.3 进阶使用
自定义过滤器类,实现复杂的过滤筛选
视图
from rest_framework import serializers from rest_framework.viewsets import ModelViewSet from django_filters.rest_framework import DjangoFilterBackend, OrderingFilter from django_filters import FilterSet, filters from app01 import models class UserModelSerializer(serializers.ModelSerializer): level_text = serializers.CharField( source="get_level_display", read_only=True ) depart_title = serializers.CharField( source="depart.title", read_only=True ) extra = serializers.SerializerMethodField(read_only=True) class Meta: model = models.UserInfo fields = ["id", "username", "age", "email", "level_text", "extra", "depart_title"] def get_extra(self, obj): return 666 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=kunmzhao ) 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 def perform_create(self, serializer): """ 序列化:对请求的数据校验成功后,执行保存。""" serializer.save(depart_id=1, password="123")
'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': _(''), 'regex': _('matches regex'), 'iregex': _('matches regex'),
3.内置filter
drf源码中内置了2个filter,分别是:OrderingFilter,SearchFilter
3.1 OrderingFilter
支持排序
from rest_framework import serializers from rest_framework.viewsets import ModelViewSet from app01 import models from rest_framework.filters import OrderingFilter class UserModelSerializer(serializers.ModelSerializer): level_text = serializers.CharField( source="get_level_display", read_only=True ) depart_title = serializers.CharField( source="depart.title", read_only=True ) extra = serializers.SerializerMethodField(read_only=True) class Meta: model = models.UserInfo fields = ["id", "username", "age", "email", "level_text", "extra", "depart_title"] def get_extra(self, obj): return 666 class UserView(ModelViewSet): filter_backends = [OrderingFilter, ] # ?ordering=id # ?ordering=-id # ?ordering=age ordering_fields = ["id", "age"] queryset = models.UserInfo.objects.all() serializer_class = UserModelSerializer def perform_create(self, serializer): """ 序列化:对请求的数据校验成功后,执行保存。""" serializer.save(depart_id=1, password="123")
3.2 SearchFilter
支持模糊搜索。
from rest_framework import serializers from rest_framework.viewsets import ModelViewSet from app01 import models from rest_framework.filters import SearchFilter class UserModelSerializer(serializers.ModelSerializer): level_text = serializers.CharField( source="get_level_display", read_only=True ) depart_title = serializers.CharField( source="depart.title", read_only=True ) extra = serializers.SerializerMethodField(read_only=True) class Meta: model = models.UserInfo fields = ["id", "username", "age", "email", "level_text", "extra", "depart_title"] def get_extra(self, obj): return 666 class UserView(ModelViewSet): # ?search=坤%赵 filter_backends = [SearchFilter, ] search_fields = ["id", "username", "age"] queryset = models.UserInfo.objects.all() serializer_class = UserModelSerializer def perform_create(self, serializer): """ 序列化:对请求的数据校验成功后,执行保存。""" serializer.save(depart_id=1, password="123")