14-1 过滤搜索排序-DRF过滤

目录:

  • DRF过滤介绍
  • 利用get_queryset过滤
  • django-filter过滤
  • 自定义过滤

一、DRF过滤介绍

我们之前写的结构其实都没有进行过滤,比如说,我们根据id升序或者降序-id,发现结果都是一样的,我们一起用postman来测试看看。

postman升序测试:127.0.0.1:8000/api/game.json?ordering=id

postman测试降序:127.0.0.1:8000/api/game.json?ordering=-id

为啥呐,我的升序和降序都是一样的呐,后面我们在仔细看看,原来你用的数据源都是一样的,都是 queryset = Game.objects.all()。

二、利用get_queryset过滤

 query_set是我们的get_queryset方法提供的,我们只需要重写 get_queryset方法就可以了。如下:

from .custom_model_view_set import CustomModelViewSet
class GameView(CustomModelViewSet):
    queryset = Game.objects.all()
    serializer_class = GameSerializer
    
    def get_queryset(self):
        ordering = self.request.query_params.get('ordering')  #获取参数
        if not ordering:
            queryset = Game.objects.all()
        else:
            queryset = Game.objects.all().order_by(ordering)  #利用django降序
        return queryset

好的,我们再来测试一下:127.0.0.1:8000/api/game.json?ordering=-id

三、django-filter过滤

django-filter库包括一个DjangoFilterBackend类,它支持REST框架的高度可定制的字段过滤。

3.1、安装

pip install django-filter

3.2、官网和github

https://django-filter.readthedocs.io/en/master/guide/rest_framework.html

https://github.com/carltongibson/django-filter

3.3、settings.py中注册

INSTALLED_APPS = [
	""""""
     'django_filters',
]

3.4、全局安装

说明:在settings.py中安装全局过滤器配置

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
       ..
    ),
    ....
    #全局配置过滤器
    'DEFAULT_FILTER_BACKENDS': (
            'django_filters.rest_framework.DjangoFilterBackend',
             ....
        ),
}

3.5、局部安装

说明:局部安装,只需要作用于某个视图,我们为了测试,我们就用局部的吧。

from .custom_model_view_set import CustomModelViewSet
#局部安装使用
from rest_framework import filters
from django_filters.rest_framework import DjangoFilterBackend


class GameView(CustomModelViewSet):

    queryset = Game.objects.all()
    serializer_class = GameSerializer

    #导入过滤器
    filter_backends = (DjangoFilterBackend,)

    #定义过滤字段,这个字段需要在模型类中存在
    filterset_fields = ('name', 'status')

postman运行结果:

单个搜索:127.0.0.1:8000/api/game.json?name=QQ 炫舞

组合搜索:127.0.0.1:8000/api/game.json?name=QQ 炫舞&status=0

四、自定义过滤

 不知道大家发现没有,上面的过滤只能是精确匹配,不能做到模糊匹配,那我们想要做到模糊匹配过滤,这个时候我们就要自定义 过滤了。跟之前还是一样需要自己新建一个 custom_filter.py,那我们的目录结构如下:

...
-app06
    -migrations
        ...
    -app.py
    -models.py
    -custom_filter.py #新建,自定义过滤
    ...
...

好啦,我们编辑  custom_filter.py,编写我们的自定义的过滤:(自定义过滤,支持模糊匹配)

from django_filters import rest_framework as filters
from .models import Game


class GameFilter(filters.FilterSet):
    min_status = filters.NumberFilter(field_name='status', lookup_expr='gte')
    max_status = filters.NumberFilter(field_name='status', lookup_expr='lte')
    #根据名字过滤忽略大小写
    name = filters.CharFilter(field_name='name', lookup_expr='icontains')

    class Meta:
        model = Game
        fields = ('min_status', 'max_status')  # 允许精准查询的字段
        search_fields = ('name',)  # 允许模糊查询的字段

具体使用方法,请查看官网:

https://django-filter.readthedocs.io/en/master/guide/rest_framework.html

这边我们就不带大家看了,我们继续,我们来修改视图:

from .custom_model_view_set import CustomModelViewSet
from django_filters.rest_framework import DjangoFilterBackend

from .custom_filter import GameFilter  #导入自定义过滤

class GameView(CustomModelViewSet):
    queryset = Game.objects.all()
    serializer_class = GameSerializer

    filter_backends = (DjangoFilterBackend,)
    # filter_fields = ('name', 'status')

    filterset_class = GameFilter  #上面的就不需要了,用我们自定义的过滤

好哒,我们再来测试一把:

单个搜素条件:http://127.0.0.1:8000/api/game.json?name=QQ

组合搜索:http://127.0.0.1:8000/api/game.json?name=QQ&min_status=1

区间值搜索:http://127.0.0.1:8000/api/game.json?min_status=0&max_status=2

posted @ 2020-05-09 17:15  帅丶高高  阅读(604)  评论(0)    收藏  举报