url?page=1&size=2
url?limit=1&offset=1
url?cursor=cj0xJnA9NQ%3D%3D
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
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 进行了多层的封装
rest_framework.viewsets
rest_framework.generics
rest_framework.mixins
# 内部提供了 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):...
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):
# 内置的操作方法 增删改查 单行数据查询都在这里
class CreateModelMixin(object): ...
class ListModelMixin(object): ...
class RetrieveModelMixin(object): ...
class UpdateModelMixin(object): ...
class DestroyModelMixin(object): ...
第一次整合
利用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'
}))
from rest_framework.renderers import JSONRenderer
from rest_framework.renderers import BrowsableAPIRenderer
from rest_framework.renderers import AdminRenderer
from rest_framework.renderers import HTMLFormRenderer
# 最后解析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
在项目的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