zoukankan      html  css  js  c++  java
  • url控制器、解析器、响应器、分页器

    url控制

    第一种写法(原生)

    from django.conf.urls import url
    from app01 import views
    urlpatterns = [
        url(r'^books/$',views.BookView.as_view()),
        url(r'^book/(?P<pk>d+)$/',views.Bookdetail.as_view())
    
    ]
    

    第二种写法(只要继承了ViewSetMixin)

    from django.conf.urls import url
    from app01 import views
    urlpatterns = [
        url(r'^publish/$',views.PublishView.as_view({'get':'list','post':'create'})),
        url(r'^publish/(?P<pk>d+)/',views.PublishView.as_view({'get':'retrieve','put':'update','delete':'destroy'}))  # 这里必须用pk,被封死了
    ]
    

    返回json格式的路由(即通过访问publish.json返回的不是页面,而是json格式的字符串)

    from django.conf.urls import url
    from app01 import views
    urlpatterns = [
        url(r'^publish.(?P<format>w+)$',views.PublishView.as_view({'get':'list','post':'create'})),
    ]
    

    第三种写法(自动生成路由,必须继承ModelViewSet)

    SimpleRouter:自动生成两条路由

    http://127.0.0.1:8000/publish/
    http://127.0.0.1:8000/publish/3
    
    from django.conf.urls import url,include
    from app01 import views
    from rest_framework.routers import SimpleRouter
    router = SimpleRouter()
    router.register('publish',views.PublishView)
    urlpatterns = [
        url(r'',include(router.urls)),
    ]
    

    DefaultRouter:自动生成四条路由

    http://127.0.0.1:8000/publish/3
    http://127.0.0.1:8000/publish.json
    http://127.0.0.1:8000/publish/3
    http://127.0.0.1:8000/publish/3.json   
    
    from django.conf.urls import url,include
    from app01 import views
    from rest_framework.routers import DefaultRouter
    router = DefaultRouter()
    router.register('publish',views.PublishView)
    urlpatterns = [
        url(r'',include(router.urls)),
    ]
    

    解析器

    一般不需要动,项目最开始全局配置一下就可以了

    作用是控制我的类能够解析前端传过来的格式是什么样的

    全局使用

    在settings配置:

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

    局部使用

    仅处理请求头content-type为application/json的请求体

    from rest_framework.parsers import JSONParser
    class TestView(APIView):
        parser_classes = [JSONParser,]
    

    仅处理请求头content-type为application/x-www-form-urlencoded 的请求体

    from rest_framework.parsers import FormParser
    class TestView(APIView):
        parser_classes = [FormParser,]
    

    仅处理请求头content-type为multipart/form-data的请求体

    from rest_framework.parsers import MultiPartParser
    class TestView(APIView):
        parser_classes = [MultiPartParser, ]
    

    仅上传文件

    from rest_framework.parsers import FileUploadParser
    class TestView(APIView):
        parser_classes = [FileUploadParser, ]
    

    源码分析

    # 1.在调用request.data时,才进行解析,由此入手
    @property
    def data(self):
        if not _hasattr(self, '_full_data'):
            self._load_data_and_files()
            return self._full_data
        
    # 2.查看self._load_data_and_files()方法--->self._data, self._files = self._parse()
    def _parse(self):
        #用户请求头里content_type的值
        media_type = self.content_type
        
        #self.parsers 就是用户配置的parser_classes = [FileUploadParser,FormParser ]
        #self里就有content_type,传入此函数
        parser = self.negotiator.select_parser(self, self.parsers)
        
    # 3.查看self.negotiator.select_parser(self,self.parsers)
    def select_parser(self, request, parsers):
        # 通过media_type和request.content_type比较,来返回解析器,然后调用解析器的解析方法
        # 每个解析器都有media_type = 'multipart/form-data'属性
        for parser in parsers:
            if media_type_matches(parser.media_type, request.content_type):
              return parser
        return None
    
    # 4.最终调用parser的解析方法来解析parsed = parser.parse(stream, media_type, self.parser_context)
    

    响应器

    不用动,就用全局配置即可

    全局使用

    'DEFAULT_RENDERER_CLASSES':[xxx,xxx]
    

    局部使用

    在视图类中配置,如果只写JSONRenderer,就返回json格式的页面

    renderer_classes = [JSONRenderer, BrowsableAPIRenderer]	
    

    版本控制

    用于控制版本

    全局使用

     'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning',
        'DEFAULT_VERSION': 'v1',  # 默认版本(从request对象里取不到,显示的默认值)
        'ALLOWED_VERSIONS': ['v1', 'v2'],  # 允许的版本
        'VERSION_PARAM': 'version',  # URL中获取值的key
        'PAGE_SIZE':2   #表示每页显示两条
    

    路由

    url(r'^(?P<version>[v1|v2]+)/test/', views.Test.as_view())
    

    在视图类中就可以通过request.version取出当前访问的是哪个版本,相应的去执行相应版本的代码

    局部使用

    from rest_framework.versioning import URLPathVersioning
    class TestView(APIView):
        versioning_class = URLPathVersioning
         def get(self, request, *args, **kwargs):
            # 获取版本
            print(request.version)
            # 获取版本管理的类
            print(request.versioning_scheme)
    
            # 反向生成URL
            reverse_url = request.versioning_scheme.reverse('test', request=request)
            print(reverse_url)
    
            return Response('GET请求,响应内容')
    

    分页

    from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination
    

    1.常规分页

    ​ 基本使用:

    ​ page = PageNumberPagination实例化产生对象

    ​ 返回值 = page.paginate_queryset(ret,request,self)

    ​ 再序列化该返回值

    ​ 四个参数:

    ​ 每页显示多少条:page.page_size = 3

    ​ 查询指定查询哪一页的key值:page.page_query_param = 'xxx'

    ​ 前端控制每页显示多少条的查询key值比如size=9,表示一页显示9条:page.page_size_query_parem = 'size'

    ​ 控制每页最大显示多少,size如果传100,最多也显示10:page.max_page_size = 10

    class PublishView(APIView):
        def get(self,request,*args,**kwargs):
            #批量添加
            # ll=[]
            # for i in range(100):
            #     ll.append(models.Publish(name='%s出版社'%i,city='%s城市'%i))
            #
            # models.Publish.objects.bulk_create(ll)
            #第一种方法,普通分页
            #查询出所有数据
            ret=models.Publish.objects.all()
            #实例化产生一个普通分页对象
            page=PageNumberPagination()
            #每页显示多少条
            page.page_size=3
            #查询指定查询哪一页的key值,例路径后面加?page=3,就是查询第三页
            page.page_query_param='page'
    
            #前端控制每页显示多少条的查询key值比如size=9,表示一页显示9条
            page.page_size_query_param='size'
            #控制每页最大显示多少,size如果传100,最多也是显示10
            page.max_page_size=10
            ret_page=page.paginate_queryset(ret,request,self)
            #序列化
            pub_ser=serializer.PublishSerializers(ret_page,many=True)
            #去setting中配置每页显示多少条,'PAGE_SIZE':2
    
            return Response(pub_ser.data)
    

    2.偏移分页

    ​ 基本使用:

    ​ page = LimitOffsetPagination实例化产生对象

    ​ 返回值 = page.paginate_queryset(ret,request,self)

    ​ 再序列化,序列化该返回值

    ​ 四个参数:

    ​ 从标杆位置往后取几个,默认取3个,可以指定:page.default_limit = 3

    ​ 每次取得条数:page.limit_query_param = 'limit'

    ​ 标杆值,现在偏移到哪个位置,如果offset=6,表示当前在第6条位置上,往后取:page.offset_query_param = 'offset'

    ​ 最大取10条:page.max_limit = 10

        def get(self, request, *args, **kwargs):
            ret = models.Publish.objects.all()
            # 实例化产生一个偏移分页对象
            page = LimitOffsetPagination()
            #四个参数:
            #从标杆位置往后取几个,默认取3个,我可以指定
            page.default_limit=3
            #每次取得条数
            page.limit_query_param='limit'
            #标杆值,现在偏移到哪个位置,如果offset=6 表示当前在第6条位置上,往后取
            page.offset_query_param='offset'
            #最大取10条
            page.max_limit=10
    
            ret_page = page.paginate_queryset(ret, request, self)
            # 序列化
            pub_ser = serializer.PublishSerializers(ret_page, many=True)
            # 去setting中配置每页显示多少条
            return page.get_paginated_response(pub_ser.data)
            # return Response(pub_ser.data)
    

    注意:get_paginated_response(pub_ser.data):调用这个方法返回的数据中会有总条数,上一页地址,下一页地址

    3.cursor游标方式

    ​ 基本使用:

    ​ page=CursorPagination实例化产生对象

    ​ 返回值=page.paginate_queryset(ret,request,self):ret是要分页的所有数据,

    ​ 再序列化,序列化该返回值

    ​ 三个参数:

    ​ 每页显示的大小:page.page_size = 3

    ​ 查询的key值:page.cursor_query_param = 'cursor'

    ​ 按什么排序:page.ordering = 'id'

        def get(self, request, *args, **kwargs):
            ret = models.Publish.objects.all()
            # 实例化产生一个偏移分页对象
            page = CursorPagination()
            #三个参数:
            #每页显示的大小
            page.page_size=3
            #查询的key值
            page.cursor_query_param='cursor'
            # 按什么排序
            page.ordering='id'
    
            ret_page = page.paginate_queryset(ret, request, self)
            # 序列化
            pub_ser = serializer.PublishSerializers(ret_page, many=True)
           
            return page.get_paginated_response(pub_ser.data)
            
    

    了解

    读源码:在取某个值之前,先反射看一下有没有,有的话直接返回,如果没有,再去执行获取这个值得方法

  • 相关阅读:
    不同主机的docker容器互相通信
    Understanding Docker
    Docker入门
    使用Docker在本地搭建Hadoop分布式集群
    Cassandra联手Spark 大数据分析将迎来哪些改变?
    Apache Spark技术实战之6 --Standalone部署模式下的临时文件清理
    大数据计算平台Spark内核全面解读
    Ubuntu下导入PySpark到Shell和Pycharm中(未整理)
    别老扯什么hadoop,你的数据根本不够大
    spark on yarn 集群部署
  • 原文地址:https://www.cnblogs.com/yanminggang/p/11140533.html
Copyright © 2011-2022 走看看