rest framework之过滤组件

一、普通过滤

1、get_queryset

  get_queryset方法是GenericAPIView提供的一个方法,旨在返回queryset数据集,而过滤就是要在这个方法返回数据集之前对数据进行筛选,然后返回筛选后的数据即可,那么也就是要求需要重写这个方法:

    def get_queryset(self):
        """
        Get the list of items for this view.
        This must be an iterable, and may be a queryset.
        Defaults to using `self.queryset`.

        This method should always be used rather than accessing `self.queryset`
        directly, as `self.queryset` gets evaluated only once, and those results
        are cached for all subsequent requests.

        You may want to override this if you need to provide different
        querysets depending on the incoming request.

        (Eg. return a list of items that is specific to the user)
        """
        assert self.queryset is not None, (
            "‘%s‘ should either include a `queryset` attribute, "
            "or override the `get_queryset()` method."
            % self.__class__.__name__
        )

        queryset = self.queryset
        if isinstance(queryset, QuerySet):
            # Ensure queryset is re-evaluated on each request.
            queryset = queryset.all()
        return queryset

源码中的这个方法会从视图配置中获得queryset,然后判断是否属于QuerySet类型,如果属于,就会返回这个queryset。

2、实例

  • 请求API
class BookView(GenericViewSet):

    serializer_class = BookModelSerializer

    def get_queryset(self):
        queryset = models.Book.objects.all()
        title = self.request.query_params.get(‘title‘,None)
        if title is not None:
            queryset = models.Book.objects.filter(title=title).all()
        return queryset

    def list(self,request,*args,**kwargs):
        queryset= self.get_queryset()
        bs=self.get_serializer(queryset,many=True)
        return Response(bs.data)

路由配置:

注意如果需要过滤,url中需要加入base_name属性,并且base_name的值就是过滤参数的名称:

router=routers.DefaultRouter()
router.register(‘books‘,views.BookView,base_name="title")

生成的路由:

^books/$ [name=‘title-list‘]
^books\.(?P<format>[a-z0-9]+)/?$ [name=‘title-list‘]

请求地址:

    http://127.0.0.1:8020/books/?title=语文

二、高级过滤

  • 安装django-filter
pip install django-filter
  • 注册django-filter
INSTALLED_APPS = [
    ‘django.contrib.admin‘,
    ‘django.contrib.auth‘,
    ‘django.contrib.contenttypes‘,
    ‘django.contrib.sessions‘,
    ‘django.contrib.messages‘,
    ‘django.contrib.staticfiles‘,
    ‘app01.apps.App01Config‘,
    ‘rest_framework‘,
    ‘django_filters‘,  #注册django-filter
]
  • 设置通用过滤后端

1、全局配置

REST_FRAMEWORK = {

    ‘DEFAULT_FILTER_BACKENDS‘: (‘django_filters.rest_framework.DjangoFilterBackend‘,)

}

2、局部视图设置

import django_filters.rest_framework 

class BookView(GenericViewSet):

    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
    filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
  • 指定筛选字段

如果需求都是些简单类型的筛选,那么可以在view或viewSet里面设置一个filter_fields属性,列出所有依靠筛选的字段集合。

import django_filters.rest_framework
from rest_framework.viewsets import ModelViewSet

class BookView(ModelViewSet):

...
    filter_fields = (‘title‘,) #列出搜索字段
...
  • 进行访问

1、路由配置

from rest_framework import routers
router=routers.DefaultRouter()router.register(‘books‘,views.BookView) #无需base_name参数
urlpatterns = [
        re_path(‘‘,include(router.urls)),
]

2、生成的路由

^books/$ [name=‘book-list‘]
^books\.(?P<format>[a-z0-9]+)/?$ [name=‘book-list‘]
^books/(?P<pk>[^/.]+)/$ [name=‘book-detail‘]
^books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name=‘book-detail‘]

3、进行访问

http://127.0.0.1:8020/books/?title=语文
  • FilterSet

上面所搜索的字段是一对一的关系,没有涉及到外键以及多对多字段,如果有外键或者多对多关系,可以在filter_fields中使用‘__’进行跨越:

class BookView(ModelViewSet):

    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
    filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
    # 列出搜索字段,其中publish__name为ForeignKey字段,authors__name为ManyToMany字段
    filter_fields = (‘title‘,‘publish__name‘,‘authors__name‘) 

class Book(models.Model):
    title=models.CharField(max_length=32)
    price=models.IntegerField()
    pub_date=models.DateField(null=True,blank=True)
    publish=models.ForeignKey("Publish",on_delete=models.CASCADE)
    authors=models.ManyToManyField("Author")
    def __str__(self):
        return self.title

models

此时请求地址:

 #含外键
http://127.0.0.1:8020/books/?title=语文&publish__name=北京出版社

#含多对多
http://127.0.0.1:8020/books/?title=语文&publish__name=北京出版社&authors__name=张三

但这样外键和多对多将Django的双下划线约定作为API的一部分暴露出来。如果想显式地命名过滤器参数,可以显式地将它包含在FilterSet类中:

1、定义FilterSet类

import django_filters
from app01 import models

class BookFilter(django_filters.rest_framework.FilterSet):
    publish = django_filters.CharFilter(field_name="publish__name")
    authors = django_filters.CharFilter(field_name="authors__name")
    class Meta:
        model = models.Book
        fields = [‘title‘, ‘publish‘, ‘authors‘]

2、在视图中使用定义的FilterSet类

class BookView(ModelViewSet):

    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
    filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
    filter_class = BookFilter #使用定义的FilterSet类

此时请求地址:

http://127.0.0.1:8020/books/?title=语文&publish=北京出版社&authors=张三

3、总结

FilterSet可以实现较为复杂的过滤功能,如果是普通字段可以使用filter_fields 添加字段进行过滤,如果有外键、多对多以及范围(日期范围、价格范围)使用FilterSet.

三、其它

1、搜索过滤(SearchFilter)

支持基于简单查询参数的搜索,并且基于Django admin的搜索功能。

  • 设置过滤后端
from rest_framework import filters

class BookView(ModelViewSet):

...
    filter_backends = (filters.SearchFilter,)
...
  • 设置查询字段
from rest_framework import filters

class BookView(ModelViewSet):

    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
    # filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
    filter_backends = (filters.SearchFilter,)

   #凡是以下字段内容都会被搜到
    search_fields = (‘title‘,‘publish__name‘,‘authors__name‘)

当然可以通过在search_fields 前面添加各种字符来限制搜索行为:

‘^‘ 以指定内容开始.

‘=‘ 完全匹配

‘@‘ 全文搜索(目前只支持Django的MySQL后端)

‘$‘ 正则搜索

例如:

search_fields = (‘=title‘,)
  • 客户端访问
#将北京出版社的内容全部搜索出来
http://127.0.0.1:8020/books/?search=北京出版社
#将张三相关内容搜索出来
http://127.0.0.1:8020/books/?search=张三

通过关键词search进行搜索,可以搜索后端search_fields提供字段的内容。

SearchFilters类的默认搜索关键字为search,可以通过SEARCH_PARAM进行覆盖设置

class BookView(ModelViewSet):
...
    SEARCH_PARAM = ‘ss‘
...

2、排序筛选(OrderingFilter)

  • 设置排序筛选后端
from rest_framework import filters

class BookView(ModelViewSet):

...
    filter_backends = (filters.OrderingFilter,)
...
  • 指定支持排序的字段(ordering_fields )
from rest_framework import filters

class BookView(ModelViewSet):
...
    filter_backends = (OrderingFilter,)
    ordering_fields = (‘title‘, ‘id‘) #指定支持排序的字段
...
  • 客户端访问

通过关键字ordering请求返回的数据按照什么排序

#按照title排序
http://127.0.0.1:8020/books/?ordering=title

#按照id排序
http://127.0.0.1:8020/books/?ordering=id
#按照id逆序
http://127.0.0.1:8020/books/?ordering=-id

#按照多个字段排序
http://127.0.0.1:8020/books/?ordering=id,title
  • 默认排序

如果需要在返回的数据中已经排好序了,可以在视图中使用ordering参数:

from rest_framework import filters

class BookView(ModelViewSet):

    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
    filter_backends = (filters.OrderingFilter,)
    ordering_fields = (‘title‘, ‘id‘)
    ordering=(‘-id‘,) #默认排序

客户端访问:

    http://127.0.0.1:8020/books/

返回的是已经按照id逆序排列的数据。

参考文档:https://q1mi.github.io/Django-REST-framework-documentation/api-guide/filtering_zh/#filtering

原文地址:https://www.cnblogs.com/shenjianping/p/11511978.html

时间: 2024-11-02 21:26:50

rest framework之过滤组件的相关文章

Spring自动注解装配、自动检测装配Bean配合过滤组件使用

自动注解装配 当我们使用注解装配时,需要在XML文件中配置: <context:annotation-config/>那么我们就可以使用基于注解的自动装配 Spring支持几种不同的自动注解装配 [email protected] :Spring会尝试使用byType的自动装配方式 例如:  @Autowired publicPeople(Language language) { this.language =language; language.say(); } @Autowired pub

DRF框架(八)——drf-jwt手动签发与校验、过滤组件、筛选组件、排序组件、分页组件

自定义drf-jwt手动签发和校验 签发token源码入口 前提:给一个局部禁用了所有 认证与权限 的视图类发送用户信息得到token,其实就是登录接口,不然进不了登录页面 获取提交的username和password 1)rest_framework_jwt.views.ObtainJSONWebToken 的 父类 JSONWebTokenAPIView 的 post 方法 接受有username.password的post请求校验数据,并且签发token 2)post方法将请求数据交给 r

签发token、校验token、多方式登录签发token的实现、自定义认证反爬规则的认证类、admin使用自定义User表:新增用户密码密文、群查接口各种筛选组件数据准备、drf搜索过滤组件、drf排序过滤组件、drf基础分页组件

签发token 源码入口 # 前提:给一个局部禁用了所有 认证与权限 的视图类发送用户信息得到token,其实就是登录接口 # 1)rest_framework_jwt.views.ObtainJSONWebToken 的 父类 JSONWebTokenAPIView 的 post 方法 # 接收有username.password的post请求 # 2)post方法将请求得到的数据交给 rest_framework_jwt.serializer.JSONWebTokenSerializer 处

过滤组件

过滤组件 群查排序过滤器 drf写好的 第一步 from rest_framework.filters import OrderingFilter 第二步 局部配置过滤器 filter_backends = [OrderingFilter,] 参与排序的字段: ordering=-price,id ordering_fields = ['price', 'id', 'students'] 第三步 请求链接样式 http://127.0.0.1:8080?ordering=-price,id 价格

分页过滤组件

复习 """ 1.celery框架 定义:异步任务框架 - 独立运行的服务器,由三部分组成 内部有socekt,可以起worker(执行任务)及beat(提交任务)两种socket 三部分包含:存储任务的broker + 执行任务的worker + 存储结果的backend app_worker = Celery(broker, backend, include) 作用: 任务:@app.task装饰的函数 异步任务:任务.delay() => 处理耗时的需求 延迟任务

DRF的分页组件,过滤组件

目录 一.DRF中的分页组件 1. 分页组件的使用 二.DRF的过滤组件 1. 搜索过滤组件的使用 2. 排序过滤组件的使用 3. 自定义过滤类 三.过滤组件之分类与区间 1. 分类与区间的使用 四.VUE前端播放器组件 一.DRF中的分页组件 DRF自带的分页组件帮我们写好了分页功能,包括各种小问题的优化,已经能满足实际开发的需求. 这里介绍了DRF的两种分页组件 基础分页组件 偏移分页组件 1. 分页组件的使用 使用方法:类似DRF的序列化的使用方式 1. 新建一个pagination.py

DRF ---- 过滤组件 分页组件 过滤组件插件使用

目录 DRF过滤组件 1 源码分析: 2 全局配置 过滤 类们 3 局部配置 过滤 类们 4 系统提供 过滤 类们 OrderingFilter(排序过滤) SearchFilter(查询过滤) 联合使用 DRF分页组件 1 全局配置 2 局部配置 3 PageNumberPagination基础分页 4 LimitOffsetPagination偏移分页 5 CursorPagination游标分页 加密分页(了解) 6.自定义过滤器 7 django-filter 过滤插件(重点) 安装 自

django rest framework 解析器组件 接口设计,视图组件 (1)

一.解析器组件 -解析器组件是用来解析用户请求数据的(application/json), content-type 将客户端发来的json数据进行解析 -必须适应APIView -request.data触发 二.序列化组件 2.1.django 自带组件serializer 2.1.1 from django.serializers import serialize2.1.2 origin_data = Book.objects.all()2.1.3 serialized_data = se

django rest framework的十个组件

Django Rest Framework 是一个强大且灵活的工具包,用以构建Web API .Django REST Framework可以在Django的基础上迅速实现API,并且自身还带有WEB的测试页面,可以方便的测试自己的API.简单说一下这个工具包的十个功能: 1.权限 2.认证 3.访问频率 4.序列化 (使用最多) 5.路由 6.视图 7.分页器 8.解析器 9.渲染器 10.版本 原文地址:https://www.cnblogs.com/zivli/p/10321771.htm