分页

看第n页,每页显示n条数据

from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination

class MyPageNumberPagination(PageNumberPagination):
    page_query_param = 'page'  # 跟的参数?page=2代表拿第二页的数据
    page_size_query_param = 'size'  # ?size=5代表一页展示5个
    max_page_size = 5  # 最大size的值为5


class Pager1View(APIView):
    def get(self, request, *args, **kwargs):
        roles = models.Role.objects.all()  # 获取所有数据
        page = MyPageNumberPagination()  # 创建分页对象,这里用了自定义的类,也可以直接用PageNumberPagination
        pager_rolse = page.paginate_queryset(
            queryset=roles, request=request, view=self)  # 对queryset进行分页,得到分页后的queryset
        ser = Pager1Serializers(instance=pager_rolse, many=True)  # 对分页后的queryset进行序列化
        return page.get_paginated_response(ser.data)  # 更好看,用return Response(ser.data)也可

在n个位置,向后查看n条数据

from rest_framework.pagination import LimitOffsetPagination  #可以通过在url中配置索引offset和limit

class Pager1View(APIView):
    def get(self, request, *args, **kwargs):
        roles = models.Role.objects.all()  # 获取所有数据

        """
        http://127.0.0.1:8000/api/v1/pager1/?offset=2 查看id=3的数据
        http://127.0.0.1:8000/api/v1/pager1/?offset=2&limit=3 查看id=3的数据一共显示3条
        可以通过配置max_limit配置一共能取多少条一页
        """
        page = LimitOffsetPagination()
        pager_rolse = page.paginate_queryset(
            queryset=roles, request=request, view=self)  # 对queryset进行分页,得到分页后的queryset
        ser = Pager1Serializers(instance=pager_rolse, many=True)  # 对分页后的queryset进行序列化

        return page.get_paginated_response(ser.data)

加密分页,对于页码进行了加密

from rest_framework.pagination import CursorPagination

class MyCursorPagination(CursorPagination):
    ordering = 'id'  # 源码默认为'-created'这里设置为通过id排序

class Pager1View(APIView):
    def get(self, request, *argys, **kwargs):
        roles = models.Role.objects.all()  # 获取所有数据
        page = MyCursorPagination()
        pager_rolse = page.paginate_queryset(
            queryset=roles, request=request, view=self)  # 对queryset进行分页,得到分页后的queryset
        ser = Pager1Serializers(instance=pager_rolse, many=True)  # 对分页后的queryset进行序列化

        return page.get_paginated_response(ser.data)

image.png
CursorPagination对页码进行了加密

视图

1、GenericView

class View1View(GenericAPIView):
    queryset = models.Role.objects.all()
    serializer_class = Pager1Serializers
    pagination_class = MyCursorPagination

    def get(self, request, *argys, **kwargs):
        roles = self.get_queryset()  # 获取数据
        pager_roles = self.paginate_queryset(roles)  # 分页
        ser = self.get_serializer(instance=pager_roles, many=True)  # 序列化
        return Response(ser.data)

2、GenericViewSet

因为GenericViewSet重写了as_view()这个方法,所以我们需要在urls.py中重新做配置

对于在urls.py中的配置

url(r'^(?P<version>[v1|v2]+)/view1/$', views.View1View.as_view({'get':'list')),

as_view()里面的字典表示当是get请求的时候,会自动分发到View1View的list方法上
所以也可以加上例如{'post':'hahaha'}这样的字典,当时post请求的时候,就自动分发到hahaha这个方法上

在views.py中,只需要将方法名改为字典中对应的值即可,因为GenericViewSet同样继承自GenericView所以整体的写法上没有差别

3、ModelViewSet(终极!!)

ModelViewSet继承自

class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):
    """
    A viewset that provides default `create()`, `retrieve()`, `update()`,
    `partial_update()`, `destroy()` and `list()` actions.
    """
    pass

可以看到覆盖了增删改查所有的Mixin
所以我们只需要在我们的url中配置好as_view()即可

url(r'^(?P<version>[v1|v2]+)/v1/$', views.View1View.as_view({'get':'list','post':'create'})),
    url(r'^(?P<version>[v1|v2]+)/v1/(?P<pk>\d+)/$', views.View1View.as_view({'get':'retrieve','delete':'destroy','put':'update','patch':'partial_update'})),

这样当我们去访问的时候就会分别对应到不同的方法下面
image.png

路由

我们可以通过注册路由的方式来简化我们的url的编写

from rest_framework import routers

router = routers.DefaultRouter()
router.register(r'v1',views.View1View)  # 第一个参数是我们设置的url的名字,第二个参数就是视图函数

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^',include(router.urls))
]

这样会自动帮助我们生成好增删改查的路由,同时我们还可以通过http://127.0.0.1:8000/api/v1/1.json的方式直接获取到json数据

如果我们自己写就需要通过如下的方式

url(r'^(?P<version>[v1|v2]+)/v1\.(?P<format>\w+)/$', views.View1View.as_view({'get':'list','post':'create'})),
url(r'^(?P<version>[v1|v2]+)/v1/(?P<pk>\d+)\.(?P<format>\w+)/$', views.View1View.as_view({'get':'retrieve','delete':'destroy','put':'update','patch':'partial_update'})),

渲染

因为对于数据的返回,前面我们选择了Respose,如果想通过渲染器针对不同的访问渲染定制化的数据,就得通过我们的渲染器
我们可以指定renderer_classes

from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer


class TestView(APIView):
    renderer_classes = [JSONRenderer, BrowsableAPIRender]

这样如果访问.json的时候就是JSONRenderer进行渲染,如果是在浏览器就行访问就是通过BrowsableAPIRender来进行渲染

同时我们也可以通过设置全局设置,完成所有视图的渲染

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

版权声明:本文为原创文章,版权归 heroyf 所有。
本文链接: https://heroyf.club/2019/07/django_learn6/


“苹果是给那些为了爱选择死亡的人的奖励”