在drf开发中有一个常用的第三方过滤器:DjangoFilterBackend。

  1. pip install django-filter

注册app:

  1. INSTALLED_APPS = [
  2. ...
  3. 'django_filters',
  4. ...
  5. ]

基本搜索

  1. # views.py
  2. from rest_framework import serializers
  3. from rest_framework.viewsets import ModelViewSet
  4. from django_filters.rest_framework import DjangoFilterBackend
  5. from app01 import models
  6. class UserModelSerializer(serializers.ModelSerializer):
  7. level_text = serializers.CharField(
  8. source="get_level_display",
  9. read_only=True
  10. )
  11. extra = serializers.SerializerMethodField(read_only=True)
  12. class Meta:
  13. model = models.UserInfo
  14. fields = ["username", "age", "email", "level_text", "extra"]
  15. def get_extra(self, obj):
  16. return 666
  17. class UserView(ModelViewSet):
  18. filter_backends = [DjangoFilterBackend, ]
  19. filterset_fields = ["id", "age", "email"]
  20. queryset = models.UserInfo.objects.all()
  21. serializer_class = UserModelSerializer
  22. def perform_create(self, serializer):
  23. """ 序列化:对请求的数据校验成功后,执行保存。"""
  24. serializer.save(depart_id=1, password="123")

复杂搜索

类的方式配置搜索条件
FilterSetfilters

  1. from rest_framework import serializers
  2. from rest_framework.viewsets import ModelViewSet
  3. from django_filters.rest_framework import DjangoFilterBackend
  4. from django_filters import FilterSet, filters
  5. from app01 import models
  6. class UserModelSerializer(serializers.ModelSerializer):
  7. level_text = serializers.CharField(
  8. source="get_level_display",
  9. read_only=True
  10. )
  11. depart_title = serializers.CharField(
  12. source="depart.title",
  13. read_only=True
  14. )
  15. extra = serializers.SerializerMethodField(read_only=True)
  16. class Meta:
  17. model = models.UserInfo
  18. fields = ["id", "username", "age", "email", "level_text", "extra", "depart_title"]
  19. def get_extra(self, obj):
  20. return 666
  21. class MyFilterSet(FilterSet):
  22. depart = filters.CharFilter(field_name="depart__title", lookup_expr="exact")
  23. min_id = filters.NumberFilter(field_name='id', lookup_expr='gte')
  24. class Meta:
  25. model = models.UserInfo
  26. fields = ["min_id", "depart"]
  27. class UserView(ModelViewSet):
  28. filter_backends = [DjangoFilterBackend, ]
  29. filterset_class = MyFilterSet
  30. queryset = models.UserInfo.objects.all()
  31. serializer_class = UserModelSerializer
  32. def perform_create(self, serializer):
  33. """ 序列化:对请求的数据校验成功后,执行保存。"""
  34. serializer.save(depart_id=1, password="123")

高级搜索

  1. from rest_framework import serializers
  2. from rest_framework.viewsets import ModelViewSet
  3. from django_filters.rest_framework import DjangoFilterBackend, OrderingFilter
  4. from django_filters import FilterSet, filters
  5. from app01 import models
  6. class UserModelSerializer(serializers.ModelSerializer):
  7. level_text = serializers.CharField(
  8. source="get_level_display",
  9. read_only=True
  10. )
  11. depart_title = serializers.CharField(
  12. source="depart.title",
  13. read_only=True
  14. )
  15. extra = serializers.SerializerMethodField(read_only=True)
  16. class Meta:
  17. model = models.UserInfo
  18. fields = ["id", "username", "age", "email", "level_text", "extra", "depart_title"]
  19. def get_extra(self, obj):
  20. return 666
  21. class MyFilterSet(FilterSet):
  22. # /api/users/?min_id=2 -> id>=2
  23. min_id = filters.NumberFilter(field_name='id', lookup_expr='gte')
  24. # /api/users/?name=wupeiqi -> not ( username=wupeiqi )
  25. name = filters.CharFilter(field_name="username", lookup_expr="exact", exclude=True)
  26. # /api/users/?depart=xx -> depart__title like %xx%
  27. depart = filters.CharFilter(field_name="depart__title", lookup_expr="contains")
  28. # /api/users/?token=true -> "token" IS NULL
  29. # /api/users/?token=false -> "token" IS NOT NULL
  30. token = filters.BooleanFilter(field_name="token", lookup_expr="isnull")
  31. # /api/users/?email=xx -> email like xx%
  32. email = filters.CharFilter(field_name="email", lookup_expr="startswith")
  33. # /api/users/?level=2&level=1 -> "level" = 1 OR "level" = 2(必须的是存在的数据,否则报错-->内部有校验机制)
  34. # level = filters.AllValuesMultipleFilter(field_name="level", lookup_expr="exact")
  35. level = filters.MultipleChoiceFilter(field_name="level", lookup_expr="exact", choices=models.UserInfo.level_choices)
  36. # /api/users/?age=18,20 -> age in [18,20]
  37. age = filters.BaseInFilter(field_name='age', lookup_expr="in")
  38. # /api/users/?range_id_max=10&range_id_min=1 -> id BETWEEN 1 AND 10
  39. range_id = filters.NumericRangeFilter(field_name='id', lookup_expr='range')
  40. # /api/users/?ordering=id -> order by id asc
  41. # /api/users/?ordering=-id -> order by id desc
  42. # /api/users/?ordering=age -> order by age asc
  43. # /api/users/?ordering=-age -> order by age desc
  44. ordering = filters.OrderingFilter(fields=["id", "age"])
  45. # /api/users/?size=1 -> limit 1(自定义搜索)
  46. size = filters.CharFilter(method='filter_size', distinct=False, required=False)
  47. class Meta:
  48. model = models.UserInfo
  49. fields = ["id", "min_id", "name", "depart", "email", "level", "age", 'range_id', "size", "ordering"]
  50. def filter_size(self, queryset, name, value):
  51. int_value = int(value)
  52. return queryset[0:int_value]
  53. class UserView(ModelViewSet):
  54. filter_backends = [DjangoFilterBackend, ]
  55. filterset_class = MyFilterSet
  56. queryset = models.UserInfo.objects.all()
  57. serializer_class = UserModelSerializer
  58. def perform_create(self, serializer):
  59. """ 序列化:对请求的数据校验成功后,执行保存。"""
  60. serializer.save(depart_id=1, password="123")

lookup_expr有很多常见选择:

  1. 'exact': _(''),
  2. 'iexact': _(''),
  3. 'contains': _('contains'),
  4. 'icontains': _('contains'),
  5. 'startswith': _('starts with'),
  6. 'istartswith': _('starts with'),
  7. 'endswith': _('ends with'),
  8. 'iendswith': _('ends with'),
  9. 'gt': _('is greater than'),
  10. 'gte': _('is greater than or equal to'),
  11. 'lt': _('is less than'),
  12. 'lte': _('is less than or equal to'),
  13. 'in': _('is in'),
  14. 'range': _('is in range'),
  15. 'isnull': _(''),
  16. 'regex': _('matches regex'),
  17. 'iregex': _('matches regex'),

全局配置和应用:

  1. # settings.py 全局配置
  2. REST_FRAMEWORK = {
  3. 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend',]
  4. }