Django REST Framework-过滤器

7 篇文章 2 订阅

一、入门使用

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

负-大到小,正-小到大

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值