DRF的内置分页和筛选功能

Posted zhuzhizheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DRF的内置分页和筛选功能相关的知识,希望对你有一定的参考价值。

分页

PageNumberPagination

  • 配置settings.py

    REST_FRAMEWORK = { 
      "PAGE_SIZE":2
    }
  • 在视图的列表页面

    from rest_framework.pagination import PageNumberPagination 
    from rest_framework import serializers 
    class PageArticleSerializer(serializers.ModelSerializer):
      class Meta: 
      model = models.Article
        fields = "__all__" 
    class PageArticleView(APIView):
        def get(self,request,*args,**kwargs): 
          queryset =models.Article.objects.all()
            # 方式一:仅数据 
            """ 
            # 分页对象 
            page_object = PageNumberPagination() 
            # 调用 分页对象.paginate_queryset方法进行分页,得到的结果是分页之后的数据 
            # result就是分完页的一部分数据 result = page_object.paginate_queryset(queryset,request,self)
            # 序列化分页之后的数据 ser = PageArticleSerializer(instance=result,many=True) 
            return  Response(ser.data) 
            """
    
            #方式二:数据+分页信息 
            """
            page_object=PageNumberPagination()
            result=page_object.paginate_queryset(queryset,request,self)
            ser=PageArticleSerializer(instance=result,many=True)
            return  page_object.get_paginated_response(ser.data)
            """
    
            #方式三:数据+部分分页信息
          page_object=PageNumberPagination()
          result=page_object.paginate_queryset(queryset,request,self)
          ser=PageArticleSerializer(instance=result,many=True)
          return  Response({'count':page_object.page.paginator.count,'result':ser.data})

LimitOffffsetPagination

from rest_framework.pagination import PageNumberPagination 
from rest_framework.pagination import LimitOffsetPagination 
from rest_framework import serializers
class PageArticleSerializer(serializers.ModelSerializer): 
    class Meta:
        model = models.Article 
        fields = "__all__"
class HulaLimitOffsetPagination(LimitOffsetPagination): 
    max_limit = 2
class PageArticleView(APIView): 
    def get(self,request,*args,**kwargs): 
        queryset = models.Article.objects.all()
        page_object = HulaLimitOffsetPagination() 
        result = page_object.paginate_queryset(queryset, request, self) 
        ser = PageArticleSerializer(instance=result, many=True) 
        return Response(ser.data)

技术图片

扩展

DRF中有内置的serializer和PageNumberPagination方法
urls.py
url(r'^page/view/article/$', views.PageViewArticleView.as_view()),
views.py
from rest_framework.generics import ListAPIView 
class PageViewArticleSerializer(serializers.ModelSerializer): 
    class Meta: 
        model = models.Article 
        fields = "__all__" class 
PageViewArticleView(ListAPIView): 
    queryset = models.Article.objects.all() 
    serializer_class = PageViewArticleSerializer    ##内置序列化功能,但是序列化函数和功能需要自己定义
## DRF内置了分页功能,需要自己配置。
settings.py 
REST_FRAMEWORK = { 
    "PAGE_SIZE":2, 
    "DEFAULT_PAGINATION_CLASS":"rest_framework.pagination.PageNumberPagination" 
}

## 也可在类的下面写
PageViewArticleView(ListAPIView): 
    queryset = models.Article.objects.all() 
    serializer_class = PageViewArticleSerializer 
    pagination_class = PageNumberPagination

小知识扩展:类的约束

# 约束子类中必须实现f1 
class Base(object): 
    def f1(self): 
        raise NotImplementedError('asdfasdfasdfasdf') 
class Foo(Base): 
    def f1(self): 
        print(123) 
obj = Foo() 
obj.f1()

筛选

这里我们先做个练习

model表

class UserInfo(models.Model):
    """ 用户表 """
    username = models.CharField(verbose_name='用户名',max_length=32)
    password = models.CharField(verbose_name='密码',max_length=64)


class Article(models.Model):
    """ 文章表 """
    category_choices = (
        (1,'咨询'),
        (2,'公司动态'),
        (3,'分享'),
        (4,'答疑'),
        (5,'其他'),
    )
    category = models.IntegerField(verbose_name='分类',choices=category_choices)
    title = models.CharField(verbose_name='标题',max_length=32)
    image = models.CharField(verbose_name='图片路径',max_length=128) # /media/upload/....
    summary = models.CharField(verbose_name='简介',max_length=255)

    comment_count = models.IntegerField(verbose_name='评论数',default=0)
    read_count = models.IntegerField(verbose_name='浏览数',default=0)

    author = models.ForeignKey(verbose_name='作者',to='UserInfo')
    date = models.DateTimeField(verbose_name='创建时间',auto_now_add=True)

serializer

class ArticleListSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Article
        fields = "__all__"

views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from rest_framework.pagination import PageNumberPagination
from . import models

class ArticleView(APIView):
    def get(self,requset,*args,**kwargs)
        """ 获取文章列表 """
        pk = kwargs.get('pk')
        # 全部数据
        if not pk:
            # 判断用户选择了哪个板块,并筛选出该板块的全部数据,返回给用户
            condition = {}
            category = request.query_params.get('category')
            if category:
                condition['category'] = category
            queryset = models.Article.objects.filter(**condition)
            pager = PageNumberPagination()
            result = pager.paginate_queryset(queryset,request,self)
            ser = ArticleListSerializer(instance=result,many=True)
            return Response(ser.data)
        # 单条数据
        article_object = models.Article.objects.filter(id=pk).first()
        ser = PageArticleSerializer(instance=article_object,many=False)
        return Response(ser.data)

DRF内置筛选功能

上面的方法没有错,但是开发的时候很麻烦,DRF内部内置了筛选功能,供我们使用
---------正常使用---------
from rest_framework.generics import 
from rest_framework.views import APIView
from rest_framework.filters import BaseFilterBackend
from rest_framework import serializers
from rest_framework.pagination import PageNumberPagination

class ArticleFilterBackend(BaseFilterBackend)
    def filter_queryset(self,request,queryset,view)
        val = request.query_params('cagetory')
        return queryset.filter(cagetory=val)


class ArticleView(APIView):
        """ 获取文章列表 """
        pk = kwargs.get('pk')
        # 全部数据
        if not pk:
            # 判断用户选择了哪个板块,并筛选出该板块的全部数据,返回给用户
            queryset = models.Article.objects.all()
            obj = ArticleFilterBackend()
            # 筛选之后的queryset
            queryset = obj.filter_queryset(request,queryset,self)
            pager = PageNumberPagination()
            result = pager.paginate_queryset(queryset,request,self)
            ser = ArticleListSerializer(instance=result,many=True)
            return Response(ser.data)
        # 单条数据
        article_object = models.Article.objects.filter(id=pk).first()
        ser = PageArticleSerializer(instance=article_object,many=False)
        return Response(ser.data)
    

---------使用内置筛选---------
class ArticleView(APIView):
        """ 获取文章列表 """
    queryset = models.News.objects.all()
    serializer_class = NewSerializers
    pagination_class = PageNumberPagination
    filter_backends = [NewFilterBackend, ]      ###内置筛选功能

    
        

以上是关于DRF的内置分页和筛选功能的主要内容,如果未能解决你的问题,请参考以下文章

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

drf-过滤组件

drf框架 token签发与校验过滤/筛选/排序/分页组件

带有分页和排序的 Spring Boot JPA 规范 API

小峰mybatismybatis分页和缓存

drf之分页器