zoukankan      html  css  js  c++  java
  • drf 下的 url控制 解析器 响应器 版本控制 分页

    一、url  控制
    
    前戏准备:
    
    models.py:
    
    
    class Author(models.Model):
        name = models.CharField(max_length=32)
        age = models.IntegerField()
        hobby = models.IntegerField(choices=((1,'basketball'),(2,'soccer'),(3,'baseball')),default=1)
    
    
    class Book(models.Model):
        title = models.CharField(max_length=32)
        publish = models.CharField(max_length=32)
        create_time = models.DateTimeField(auto_now_add=True)
        author = models.ManyToManyField(to='Author')
    
    自定义文件下:Myserializer.py
    
    from app01 import models
    from rest_framework.serializers import ModelSerializer,Serializer,SerializerMethodField
    from rest_framework import serializers
    
    class AuthorSerializer(ModelSerializer):
        class Meta:
            model = models.Author
            fields = '__all__'
            
        # 可以解决choice字段前端可以取道想要的表示数据,发到后端的时候,发对应的序号就行,好用
        hobby = serializers.SerializerMethodField()
        def get_hobby(self,obj):
            return obj.get_hobby_display()
    
    class BookSerializer(ModelSerializer):
        class Meta:
            model = models.Book
            fields = '__all__'
    
    视图层
    
    from app01 import models
    from app01.MyseriaLizer import AuthorSerializer ,BookSerializer
    from rest_framework.viewsets import ModelViewSet
    
    class Author(ModelViewSet):
    
        queryset = models.Author.objects.all()
        serializer_class = AuthorSerializer
    
    
    class Book(ModelViewSet):
        queryset = models.Book.objects.all()
        serializer_class = BookSerializer
    
    路由层:
    
    from django.conf.urls import url,include
    from django.contrib import admin
    from app01 import views
    from rest_framework.routers import SimpleRouter,DefaultRouter
    
    
    #使用 Simplerouter  自动生成两种路由
    
    router = SimpleRouter()
    router.register('book',views.Book)
    router.register('author',views.Author)
    #多个路由直接再注册一次就ok
    
     url(r'',include(router.urls))
    
    
    其自动生成的路径为:
    
    ^book/$ [name='book-list']
    ^book/(?P<pk>[^/.]+)/$ [name='book-detail']
    ^author/$ [name='author-list']
    ^author/(?P<pk>[^/.]+)/$ [name='author-detail']
    
    
    #使用 DefaultRouter  自动生成6种路由
    router = DefaultRouter()  #用法一样,将类换一下即可
    router.register('book',views.Book)
    
        url(r'',include(router.urls))
    
    其自动生成的路径:
    ^book/$ [name='book-list']
    ^book.(?P<format>[a-z0-9]+)/?$ [name='book-list']
    ^book/(?P<pk>[^/.]+)/$ [name='book-detail']
    ^book/(?P<pk>[^/.]+).(?P<format>[a-z0-9]+)/?$ [name='book-detail']
    ^$ [name='api-root']
    ^.(?P<format>[a-z0-9]+)/?$ [name='api-root']
    二、解析器
    
    -解析器(一般不需要动,项目最开始全局配置一下就可以了) 
    -作用是控制我的视图类能够解析前端传过来的格式是什么样的
    
    在视图层使用
    
    from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
    class Author(ModelViewSet):
        renderer_classes = [JSONRenderer,]  #局部使用
        queryset = models.Author.objects.all()
        serializer_class = AuthorSerializer
    
    全局使用:
    先在settings里配置:
    REST_FRAMEWORK = {
                        "DEFAULT_PARSER_CLASSES":[
                            'rest_framework.parsers.JSONParser',
                        ]
                    }
    局部使用:直接在视图类中使用:parser_classes=[JSONParser,]
    三、版本控制
    
    用来版本的控制
    
    drf内置的版本控制类:
    from rest_framework.versioning import QueryParameterVersioning,AcceptHeaderVersioning,NamespaceVersioning,URLPathVersioning
    
    #基于url的get传参方式:QueryParameterVersioning------>如:/users?version=v1
    #基于url的正则方式:URLPathVersioning------>/v1/users/
    #基于 accept 请求头方式:AcceptHeaderVersioning------>Accept: application/json; version=1.0
    #基于主机名方法:HostNameVersioning------>v1.example.com
    #基于django路由系统的namespace:NamespaceVersioning------>example.com/v1/users/
    
    
    
    局部使用:在CBV类中加入
    versioning_class = URLPathVersioning
    
    全局使用:
    REST_FRAMEWORK = {
        'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning',
        'DEFAULT_VERSION': 'v1',            # 默认版本(从request对象里取不到,显示的默认值)
        'ALLOWED_VERSIONS': ['v1', 'v2'],   # 允许的版本
        'VERSION_PARAM': 'version'          # URL中获取值的key
    }
    
    
    路由层:
    
    urlpatterns = [
        url(r'^(?P<version>[v1|v2]+)/test/', TestView.as_view(), name='test'),
    ]
    
    
    
    视图层:
    from rest_framework.views import APIView
    from rest_framework.response import Response
    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请求,响应内容')
    
    
    
    补充:
    # 基于django内置,反向生成url
            from django.urls import reverse
            url2=reverse(viewname='ttt',kwargs={'version':'v2'})
            print(url2)
    批量插入数据:
    def get(self,request,*args,**kwargs):
          li = []
            for i in range(100):
                li.append(models.Test(classes='%s班级'%i,grade='第%s人'%i))
            models.Test.objects.bulk_create(li)
            return Response()
    四、分页器
    
    常规分页:
      基本使用:
    from rest_framework.pagination import PageNumberPagination
    
    class Test(APIView):
        def get(self,request,*args,**kwargs):
            #获得所有要分页的数据
            ret = models.Test.objects.all()
            # 实例化产生对象
            page = PageNumberPagination()
            #  控制每页显示的条数
            page.page_size = 5  # 这一步也可交给settings配置,不过需要记住优先顺序!
            # 指定查询哪一页的key值,在url后输入即可,记得带上?
            page.page_query_param = 'page'
            前端控制每页显示多少条的查询key值  可以改变改变默认值
             page.page_size_query_param = 'size'
            # 控制每页最多显示的条数
            page.max_page_size = 10
            #在数据库中获取分页的数据
            ret_page = page.paginate_queryset(ret,request,view=self)
            test_ser = TestSerializer(instance=ret_page,many=True)
           # return Response(test_ser.data)  正常使用
           #这个也是返回Response对象,但是比基本的多了上一页,下一页,和总数据条数
            return page.get_paginated_response(ser.data)



    路由层: url(r
    '^test/',views.Test.as_view()) 自定义序列化层: class TestSerializer(ModelSerializer): class Meta: model = models.Test fields = '__all__'      #exclude = (当前的不会出现,其他的会有的) 注:在使用过程中发现 :会报错,但不影响代码的执行 UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list 经过google查询资料,发现是获取所有queryset对象时没有排序! 因此只需要获取数据时: ret = models.Test.objects.all().order_by('pk')即可

    对于上述default_limit配置无效的解决:
    注意代码的顺序:即将
    ret_page = page.paginate_queryset(ret, request, view=self)
    test_ser = TestSerializer(instance=ret_page,many=True)
    放置最后即可!


    偏移分页: LimitOffsetPagination
    from rest_framework.pagination import LimitOffsetPagination
    class Test(APIView):
    def get(self, request, *args, **kwargs):
    ret = models.Test.objects.all().order_by('pk')
    # 实例化产生对象
    page = LimitOffsetPagination()
    # 固定写法
    ret_page = page.paginate_queryset(ret,request,view=self)
    # page.default_limit = 2 不知为何,这种配置没用,只能手动指定 limit 的数字,显示多少条
    page.limit_query_param = 'limit'
    #标杆值,现在偏移到哪个位置
    page.offset_query_param = 'offset'
    # 最大往后去的条数
    page.max_limit = 10
    test_ser = TestSerializer(instance=ret_page,many=True)
    return Response(test_ser.data)





    加密分页 :只能看上一页,下一页,查询速度快 CursorPagination
    from rest_framework.pagination import CursorPagination
    class Test(APIView):
    def get(self,request,*args,**kwargs):
    page = CursorPagination()
    ret = models.Test.objects.all()
    # 每页显示的大小
    page.page_size = 3
    #查询的key值
    page.cursor_query_param = 'cursor'
    # 按什么来排序
    page.ordering = 'id'
    ret_page = page.paginate_queryset(ret,request,view=self)
    page_ser = TestSerializer(instance=ret_page,many=True)
    # 使用get_paginated_response 可以避免页码被猜到
    return page.get_paginated_response(page_ser.data)
  • 相关阅读:
    [转]google gflags 库完全使用
    机器学习者面试,看这10个建议
    分享10个数据分析的小技巧(Python)
    工作学习上实用的编程相关知识分享
    前端React 框架- UmiJS有听说过吗?
    PyTorch如何构建深度学习模型?
    Sigmoid 和 Softmax 如何进行函数处理分类?
    从零开始学习机器学习最简单的 kNN 算法
    监督学习中的决策树算法(含代码)
    可视化Bert网络,发掘其中真实世界的嵌入
  • 原文地址:https://www.cnblogs.com/changwenjun-666/p/11140892.html
Copyright © 2011-2022 走看看