Django DRF 分页、视图、路由、渲染

一、分页

1.1、分页的三种方法

  • PageNumberPagination
url?page=1&size=2
  • LimitOffsetPagination 从第几个到第几个
url?limit=1&offset=1
  • CursorPagination 【游标分页会加密,更安全】
url?cursor=cj0xJnA9NQ%3D%3D

1.2、实例

PageNumberPagination

from rest_framework.pagination import PageNumberPagination

class MyPagination(PageNumberPagination):
    # url?page=1&size=2
    page_size = 2  # 每页多少个
    page_query_param = 'page'
    page_size_query_param = 'size'
    max_page_size = 3 # 最大每页展示多少条

LimitOffsetPagination 从第几个到第几个

from rest_framework.pagination import LimitOffsetPagination

class MyPagination(LimitOffsetPagination):
    # url?limit=1&offset=1
    default_limit = 1  # 默认向后找x条
    limit_query_param = 'limit'
    offset_query_param = 'offset'
    max_limit = 3

CursorPagination 加密显示

from rest_framework.pagination import CursorPagination

class MyPagination(CursorPagination):
    cursor_query_param = 'cursor'
    page_size = 2
    ordering = '-id'  # 排序  id倒序

1.3视图

视图1

class BookPageView(APIView):
    def get(self, request, *args, **kwargs):
        # 查看所有图书
        books = Books.objects.all().order_by('id')
        # 实例化分页器对象
        pg = MyPagination()
        # 调用实例方法去分页queryset
        pg_ = pg.paginate_queryset(queryset=books, request=request)
        # 序列化
        ser = BookSerializers(instance=pg_, many=True)
        # 带着上一页下一页的链接响应
        return pg.get_paginated_response(ser.data)

视图2(简单)

class BookView(GenericAPIView, ListModelMixin):
    queryset = Books.objects.all()
    serializer_class = BookSerializers

    def get(self, request):
        return self.list(request)
# settings.py
REST_FRAMEWORK = {
     
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 5,
}

二、视图

rest framework 进行了多层的封装

2.1、源码位置

rest_framework.viewsets  
rest_framework.generics  
rest_framework.mixins 

2.2、 rest_framework.viewsets源码

# 内部提供了 as_view 方法
class ViewSetMixin(object):
    # 此方法提供了 as_view 方法可以加参数的条件
     def as_view(cls, actions=None, **initkwargs):...

# 用作总的继承类 
class GenericViewSet(ViewSetMixin, generics.GenericAPIView): ...


# 单数据分支继承类 ,只有全数据和单数据的查看方法
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
                           mixins.ListModelMixin,
                           GenericViewSet):...

# 全数据分支继承类,最全内置增删改查 以及 单数据查看方法 5个全都有 
class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):...

2.3、rest_framework.generics源码

class GenericAPIView(views.APIView):
   # queryset 数据对象传入用变量
    queryset = None  
  # 在视图中序列化工具对象传入用变量      
    serializer_class = None


# 以下是一些增删改查的各种共功能组合 ,用于继承类使用

class CreateAPIView(mixins.CreateModelMixin,
                GenericAPIView):
class ListAPIView(mixins.ListModelMixin,
              GenericAPIView):
class RetrieveAPIView(mixins.RetrieveModelMixin,
                  GenericAPIView):
class DestroyAPIView(mixins.DestroyModelMixin,
                 GenericAPIView):
class UpdateAPIView(mixins.UpdateModelMixin,
                GenericAPIView):
class ListCreateAPIView(mixins.ListModelMixin,
                    mixins.CreateModelMixin,
                    GenericAPIView):
class RetrieveUpdateAPIView(mixins.RetrieveModelMixin,
                        mixins.UpdateModelMixin,
                        GenericAPIView):
class RetrieveDestroyAPIView(mixins.RetrieveModelMixin,
                         mixins.DestroyModelMixin,
                         GenericAPIView):
class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
                               mixins.UpdateModelMixin,
                               mixins.DestroyModelMixin,
                               GenericAPIView):

2.3、rest_framework.mixins源码

# 内置的操作方法 增删改查 单行数据查询都在这里
class CreateModelMixin(object): ...

class ListModelMixin(object): ...

class RetrieveModelMixin(object): ...

class UpdateModelMixin(object): ...

class DestroyModelMixin(object): ...

2.4、整合流程

第一次整合
利用GenericeAPIView 传入 queryset对象以及 序列化对象, 再利用内置的 mixins 中的操作方法省去操作代码

from rest_framework.generics import GenericAPIView
from rest_framework import mixins


class BooksView(GenericAPIView, mixins.ListModelMixin):
    queryset = models.Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)


class BookDetail(GenericAPIView, mixins.RetrieveModelMixin, mixins.CreateModelMixin):
    queryset = Books.objects.all()
    serializer_class = BookSerializers

    def get(self, request, pk, *args, **kwargs):
        return self.retrieve(request, pk, *args, **kwargs)
    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)
# 路由分成两条
path('books/', BookDetailView.as_view()),
path('books/', BookDetail.as_view()),

第二次整合
利用GenericeAPIView 传入 queryset对象以及 序列化对象, 再利用内置的 generics 中的操作方法省去操作代码

from rest_framework.generics import ListCreateAPIView,RetrieveUpdateDestroyAPIView

class BookDetailView(ListCreateAPIView):
    queryset = Books.objects.all()
    serializer_class = BookSerializers

class BookDetail(RetrieveUpdateDestroyAPIView):
    queryset = Books.objects.all()
    serializer_class = BookSerializers

最终整合
直接继承最终的 ModelViewSet 继承类 ,因为继承了 ViewSetMixin 类 得以可以让重写 as_view 方法能够添加参数

from rest_framework.viewsets import ModelViewSet
class BookView(ModelViewSet):
    queryset = Books.objects.all()
    serializer_class = BookSerializers
path('books/', BookView.as_view({
     'get': 'list', 'post': 'create'})),
path('books/', BookView.as_view({
     
    'get': 'retrieve',
    'put': 'update',
    'patch': 'partial_update',
    'delete': 'destroy'
}))

2.5、Django继承关系图

Django DRF 分页、视图、路由、渲染_第1张图片

三、渲染

3.1内置渲染器

from rest_framework.renderers import JSONRenderer
from rest_framework.renderers import BrowsableAPIRenderer
from rest_framework.renderers import AdminRenderer
from rest_framework.renderers import HTMLFormRenderer
  • 显示json格式:JSONRenderer
  • 默认显示格式:BrowsableAPIRenderer(可以修改它的html文件)
  • 表格方式:AdminRenderer
  • form表单方式:HTMLFormRenderer

3.2源码分析

# 最后解析reponse对象数据
self.response = self.finalize_response(request, response, *args, **kwargs) 点进去
​
# 拿到运行的解析类的对象们
neg = self.perform_content_negotiation(request, force=True) 点进去
​
# 获得解析类对象
renderers = self.get_renderers() 点进去
​
# 从视图类中得到renderer_classes请求类,如何实例化一个个对象形参解析类对象列表
return [renderer() for renderer in self.renderer_classes]
​
​
# 重点:self.renderer_classes获取renderer_classes的顺序
#   自己视图类的类属性(局部配置) => 
#   APIView类的类属性设置 => 
#   自己配置文件的DEFAULT_RENDERER_CLASSES(全局配置) => 
#   drf配置文件的DEFAULT_RENDERER_CLASSES

3.3使用

在项目的settings.py中


REST_FRAMEWORK = {
     
    'DEFAULT_RENDERER_CLASSES': ['rest_framework.renderers.JSONRenderer']
}

在views.py视图类中提供对应的类属性

class BookView(ModelViewSet):
    renderer_classes = [JSONRenderer]
    queryset = Books.objects.all()
    serializer_class = BookSerializers

你可能感兴趣的:(Django之路,django,python)