zoukankan      html  css  js  c++  java
  • django restframework解析器和分页

    解析器

    由来

    django请求的原始数据是放到request.body当中,django默认的解析器只负责解析同时满足下面两个条件的数据

    1. 请求头 Content-Type: application/x-www-form-urlencoded
    2. 数据格式要求name=alex&age=18

    只要这两个条件有一个不满足,django默认的解析器就不会把数据解析到request.POST里。

    情况一:
    $.ajax({
        url: ...
        type: POST,  # 请求头默认是 application/x-www-form-urlencoded
        data: {name: alex, age = 18}  # 内部转化 name=alex&age=18&gender=男
    })
    
    情况二:
    $.ajax({
        url: ...
        type: POST,
        headers: {'Content-Type': "application/json"}
        data: {name: alex, age = 18}  # 内部转化 name=alex&age=18&gender=男
    })
    # body有值;POST无
    情况三:
    $.ajax({
        url: ...
        type: POST,
        headers: {'Content-Type': "application/json"}
        data: JSON.stringfy({name: alex, age = 18})  # {name:alex,age:18...}
    })
    # body有值;POST无
    # json.loads(request.body)
    

    restframework提供了更多丰富的解析器能帮我们做数据解析操作

    使用

    parser是根据请求头 content-type 选择对应的解析器对符合content-type格式的请求体内容进行处理。

    from rest_framework.parsers import JSONParser, FormParser,MultiPartParser
    
    class UserView(APIView):
        parser_classes = [FormParser, JSONParser, MultiPartParser]
    
        def post(self, request, *args, **kwargs):
            print(request.content_type)
    
            # 获取请求的值,并使用对应的JSONParser进行处理
            print(request.data)
    
            # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
            print(request.POST)
            print(request.FILES)
    
            return Response('POST请求,响应内容')
    
        def put(self, request, *args, **kwargs):
            return Response('PUT请求,响应内容')
    

    全局配置

    REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES':[
            'rest_framework.parsers.JSONParser'
            'rest_framework.parsers.FormParser'
            'rest_framework.parsers.MultiPartParser'
        ]
    
    }
    

    源码流程

    只有在request.data或request.FILES或request.POST的时候才会调用解析器进行解析. 并且request.data总会有数据的,无论是上传数据还是文件,无论content-type是什么,因为request.data返回的是self._full_data.

                if self._files:
                    self._full_data = self._data.copy()
                    self._full_data.update(self._files)
                else:
                    self._full_data = self._data
    
    
    






    分页

    简单分页

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

    from rest_framework.pagination import PageNumberPagination
    
    class MyPageNumberPagination(PageNumberPagination):
        page_size = 2
        page_query_param = 'page'
        # page_size_query_param 相当于临时更改默认的page_size
        page_size_query_param = 'size'
        max_page_size = 5
    
    
    class Pager1View(APIView):
    
        def get(self,request,*args,**kwargs):
    
            # 获取所有数据
            roles = models.Role.objects.all()
    
            # 创建分页对象
            pg = MyPageNumberPagination()
    
            # 在数据库中获取分页的数据,
            pager_roles = pg.paginate_queryset(queryset=roles,request=request,view=self)
    
            # 对数据进行序列化
            ser = PagerSerialiser(instance=pager_roles, many=True)
    
            return Response(ser.data)
    

    偏移分页

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

    from rest_framework.pagination import LimitOffsetPagination
    
    class MyLimitOffsetPagination(LimitOffsetPagination):
        # limit表示页面总共显示多少条数据
        default_limit = 2
        limit_query_param = 'limit'
    
        # offset表示偏移,从0开始
        offset_query_param = 'offset'
        max_limit = 5
    
    
    class Pager1View(APIView):
    
        def get(self,request,*args,**kwargs):
    
            # 获取所有数据
            roles = models.Role.objects.all()
    
            # 创建分页对象
            # pg = MyLimitOffsetPagination()
            pg = LimitOffsetPagination()
    
            # 在数据库中获取分页的数据
            pager_roles = pg.paginate_queryset(queryset=roles,request=request,view=self)
    
            # 对数据进行序列化
            ser = PagerSerialiser(instance=pager_roles, many=True)
    
            return Response(ser.data)
    

    加密分页

    加密分页,上一页和下一页。请求url:http://127.0.0.1:8000/test/?size=1

    from rest_framework.pagination import CursorPagination
    
    class MyCursorPagination(CursorPagination):
        cursor_query_param = 'cursor'
        page_size = 2
        ordering = 'id'
        page_size_query_param = "size"
        max_page_size = 12
    
    class Pager1View(APIView):
    
        def get(self,request,*args,**kwargs):
    
            # 获取所有数据
            roles = Group.objects.all()
    
            # 创建分页对象
            # pg = CursorPagination()
            pg = MyCursorPagination()
    
            # 在数据库中获取分页的数据
            pager_roles = pg.paginate_queryset(queryset=roles,request=request,view=self)
    
            # 对数据进行序列化
            ser = GroupSerializer(instance=pager_roles, many=True)
    
            # 这里需要分页对象的get_paginated_response
            return pg.get_paginated_response(ser.data)
    

    得到的结果{"next":"http://127.0.0.1:8000/test/?cursor=cD0x&size=1","previous":null,"results":[{"g_name":"linux运维"}]}

  • 相关阅读:
    5.1点击4个按钮显示相应的div
    4.1邮箱的全选,全不选,反选
    3.1点击3个按钮变宽变高变色
    2.4点击按钮填色
    2.3点击菜单显示div再点击就隐藏
    2.2 点击按钮改变文本框中的文字内容
    linux系统编程视频 百度网盘下载
    Linux网络编程视频 百度网盘
    Sage Crm 权限原理分析
    Sage CRM 平衡区域树结构
  • 原文地址:https://www.cnblogs.com/longyunfeigu/p/9386451.html
Copyright © 2011-2022 走看看