欢迎来到赛兔子家园

过滤器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',]
}

 

posted on 2024-04-30 12:21  赛兔子  阅读(13)  评论(0编辑  收藏  举报

导航