zoukankan      html  css  js  c++  java
  • rest_framework五大模块

    面向对象封装

    面向对象封装导入

    # 1.将子类共有的方法抽离形成父类方法
    # 2.子类使用共有方法,使用的是父类方法
    # 3.共有方法中的资源,在子类使用方法时,获取的是子类资源
    class MyClass:
          name = None
          @classmethod
          def test(cls):
                print(cls.name)
    class AClass(MyClass):
          name = "AClass"
    class BClass(MyClass):
          name = "BClass"
    AClass.test()
    BClass.test()
    面向对象的封装

    drf视图层面向对象封装应用

    # drf已经做了 CBV的面向对象封装,且还做了一步精髓之笔,重写了as_view()
    class GetListClass: pass # get_list
    class PostOneClass: pass # post_one
    class GetOneCLass: pass # get_one
    class PutOneClass: pass # put_one
    class DeleteOneClass: pass # delete_one 
    
    # get_list | post_one | get_one | put_one | delete_one 
    class MyClass(GetListClass,PostOneClass,GetOneCLass,PutOneClass,DeleteOneClass): pass
    
    # get_list | post_one
    class Books(GetListClass,PostOneClass): pass
    # get_list | post_one | get_one | put_one | delete_one 
    class BookView(MyClass): pass
    # get_list | post_one | get_one | put_one | delete_one 
    class AuthorView(MyClass): pass
    drf视图层面向对象封装

    基础的五大接口:基础

    数据准备

    # settings.py 
    INSTALLED_APPS=[
      #.....
      'rest_framework',
    ]
    
    # models.py 手动形成数据
    class Book(models.Model):
        name = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=5, decimal_places=2)
        author = models.ManyToManyField(to='Author', db_constraint=False)
    
    class Author(models.Model):
        name = models.CharField(max_length=32)
        author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.SET_NULL, null=True, db_constraint=False)
    
    class AuthorDetail(models.Model):
        age = models.IntegerField()
        telephone = models.CharField(max_length=32)
        
    # objectjson.py
    from rest_framework import serializers
    from app import models
    
    class AuthorDetailJson(serializers.ModelSerializer):
        class Meta:
            model = models.AuthorDetail
            fields = '__all__'
    
    class AuthorJson(serializers.ModelSerializer):
        class Meta:
            model = models.Author
            fields = '__all__'
    
    class BookJson(serializers.ModelSerializer):
        class Meta:
            model = models.Book
            fields = '__all__'
    # urls.py
    from app import views
    urlpatterns = [
        url(r'^books/', views.Books.as_view()),
        url(r'^book/(?P<pk>d+)/', views.Book.as_view()),
    ]
    数据准备

    五大接口

    from rest_framework.views import APIView
    from rest_framework.response import Response
    from app import models, objectjson
    
    
    class Books(APIView):
        # 请求地址:/books/
        def get(self, request, *args, **kwargs):
            book_list = models.Book.objects.all()
            book_data = objectjson.BookJson(book_list, many=True).data
            return Response({
                'status': 0,
                'message': 'ok',
                'results': book_data
            })
    
        # 请求地址:/books/ 参数::{"name": "红楼梦","price": "66.66","author": [1]}
        def post(self, request, *args, **kwargs):
            book_json = objectjson.BookJson(data=request.data)
            if book_json.is_valid():
                book_json.save()
                return Response({
                    'status': 0,
                    'message': 'ok',
                    'results': book_json.data
                })
    
    
    class Book(APIView):
        # 请求地址:/book/1/
        def get(self, request, pk, *args, **kwargs):
            book = models.Book.objects.filter(pk=pk).first()
            book_data = objectjson.BookJson(book).data
            return Response({
                'status': 0,
                'message': 'ok',
                'results': book_data
            })
    
        # 请求地址:/book/2/ 参数:{"name": "红楼梦","price": "88.88","author": [1]}
        def put(self, request, pk, *args, **kwargs):
            book = models.Book.objects.filter(pk=pk).first()
            book_json = objectjson.BookJson(data=request.data, instance=book)
            if book_json.is_valid():
                book_json.save()
                return Response({
                    'status': 0,
                    'message': 'ok',
                    'results': book_json.data
                })
            return Response({
                'status': 0,
                'message': book_json.errors,
            })
    
        # 请求地址:/book/2/
        def delete(self, request, pk, *args, **kwargs):
            deleted, _ = models.Book.objects.filter(pk=pk).delete()
            if deleted != 0:
                return Response({
                    'status': 2,
                    'message': 'delete success'
                })
            return Response({
                'status': 1,
                'message': 'delete failed'
            })
    五大接口

    五大接口的基础整合:过渡

    # views.py
    from rest_framework.viewsets import ModelViewSet
    from app import models, objectjson
    
    class Books(ModelViewSet):
        queryset = models.Book.objects
        serializer_class = objectjson.BookJson
    
    class Book(ModelViewSet):
        queryset = models.Book.objects
        serializer_class = objectjson.BookJson
        lookup_field = 'pk'
    # urls.py
    from app import views
    
    urlpatterns = [
        url(r'^books', views.Books.as_view({'get': 'list', 'post': 'create'})),
        url(r'^book/(?P<pk>d+)/', views.Book.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
    ]
    # 解读
    '''
    ModelViewSet继承:五大接口的Mixin,GenericViewSet
             --五大接口的Mixin:
                     -- 分别提供 get_list(list) | post_one(create) | get_one(retrieve) | put_one(update) | delete_one(destroy)
             -- GenericViewSet:
                     -- 继承:ViewSetMixin, generics.GenericAPIView
                             -- ViewSetMixin:重写as_view():解析路由 as_view({'get':'list','post':'create'})
                             -- GenericAPIView:提供基础的 APIView,拥有请求方式
    '''
    过渡

    项目开发基于drf的cbv设计:重点

    视图模块

    # views.py
    from rest_framework.viewsets import ModelViewSet
    from rest_framework.response import Response
    from app import models, objectjson
    
    # 可以将于Book有关的所有操作函数都放在该CBV中,任何在路由层完成as_view("请求方式":"处理方法")分发
    class BookView(ModelViewSet):
        # 如果需要使用基础(没有任何业务逻辑)的五大接口
        queryset = models.Book.objects
        serializer_class = objectjson.BookJson
        lookup_field = 'pk'  # 有名分组key
    
        # 世纪开发的业务逻辑远远超出五大接口的基础逻辑范围
        # 自定义n个处理数据的函数
        def get_book_by_id(self, request, id, *args, **kwargs):
            book = models.Book.objects.filter(pk=id).first()
            book_data = objectjson.BookJson(book).data
            return Response({
                'status': 0,
                'message': 'ok',
                'results': book_data
            })
    # urls.py
    urlpatterns = [
        url(r'^book/(?P<id>d+)/', views.BookView.as_view({'get': 'get_book_by_id'})),
    ] 

    路由模块

    from app import views
    urlpatterns = [
      # 传统CBV
      url(r'^books/',views.Books.as_view()),
    ]
    urlpatterns = [
      # CBV路由的函数分发
      url(r'^books/',views.BookView.as_view({"get":"get_list"})),
    ]

    解析模块

    # views.py
    # 解析模块:form-data(MultiPartParser) from-urlencoded(FormParser) json(JSONParser)
    from rest_framework.viewsets import ModelViewSet
    from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
    from rest_framework.response import Response
    class TestParser(ModelViewSet):
        # 插拔式:选择性定制解析
        # 配置用户不同方式提交数据,服务器能否提供解析
        parser_classes = [MultiPartParser, FormParser, JSONParser]  # 局部配置即parser_classes=[]在列表中填哪个这个类就解析什么
        def post(self, request, *args, **kwargs):
            return Response({
                'status': 0,
                'message': 'TestParser',
                'results': request.data
            })
     REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES': (
            'rest_framework.parsers.JSONParser',
            'rest_framework.parsers.FormParser',
            'rest_framework.parsers.MultiPartParser'
        )
    }
    # 注释哪个就在全局不使用哪个上传数据的格式
    # urls.py 
    urlpatterns = [
        url(r'^parsers/', views.TestParser.as_view({'post': 'post'})),
    ]

    响应模块

    # views.py
    # 相应模块
    from rest_framework.viewsets import ModelViewSet
    from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
    from rest_framework.response import Response
    class TestParser(ModelViewSet):
        # 插拔式:选择性定制相应模块
        # 配置服务器提供的不同相应数据的方式
        # renderer_classes = [JSONRenderer]# 局部配置需要哪个写哪个
        def get(self, request, *args, **kwargs):
            return Response({
                'status': 0,
                'message': 'TestParser'
            })
    # settings.py
    # 全局配置
    REST_FRAMEWORK = {
                'DEFAULT_RENDERER_CLASSES': (
            'rest_framework.renderers.JSONRenderer',
            # 'rest_framework.renderers.BrowsableAPIRenderer',
        )
    }
    # 当别人在浏览器中访问你的路由,会知道你用了drf模块,在实际开发中一般禁用BrowsableAPIRenderer。
    # urls.py 
    urlpatterns = [
        url(r'^parsers/', views.TestParser.as_view({'get': 'get'})),
    ]

    版本控制模块

    基本配置

    REST_FRAMEWORK = {
        # 默认版本
        'DEFAULT_VERSION': 'v1',
        # 现存版本
        'ALLOWED_VERSIONS': ['v1', 'v2'],
        # url的参数key
        'VERSION_PARAM': 'version',
    }

    通过请求参数完成版本配置

    # api.site.com/versioning/?version=v1 | api.site.com/versioning/?version=v2
    # -- QueryParameterVersioning
    # -- url(r'^versioning/',views.TestVersioning.as_view({'get':'get'}))
    # -- 请求:/versioning/?version=v1 | /versioning/?version=v1
    from rest_framework.viewsets import ModelViewSet
    from rest_framework.response import Response
    from rest_framework.versioning import QueryParameterVersioning
    class TestVersioning(ModelViewSet):
        versioning_class = QueryParameterVersioning
    
        def get(self, request, *args, **kwargs):
            print(request.version)
            print(request.versioning_scheme)
            if request.version == 'v1':
                print('v1版本的业务逻辑')
            elif request.version == 'v2':
                print('v2版本的业务逻辑')
            return Response({
                'status': 0,
                'message': 'TestVersioning',
                'version': request.version
            })

    通过请求url完成版本配置:常用

    # api.site.com/v1/versioning/ | api.site.com/v2/versioning/
    # -- URLPathVersioning
    # -- url(r'^(?P<version>(v1|v2))/versioning/', views.TestVersioning.as_view({'get': 'get'})),
    from rest_framework.viewsets import ModelViewSet
    from rest_framework.response import Response
    from rest_framework.versioning import URLPathVersioning
    
    
    class TestVersioning(ModelViewSet):
        versioning_class = URLPathVersioning
    
        def get(self, request, *args, **kwargs):
            print(request.version)
            print(request.versioning_scheme)
            if request.version == 'v1':
                print('v1版本的业务逻辑')
            elif request.version == 'v2':
                print('v2版本的业务逻辑')
            return Response({
                'status': 0,
                'message': 'TestVersioning',
                'version': request.version
            })
  • 相关阅读:
    再谈TextField
    IOS-TextField知多少
    leftBarButtonItems
    LeftBarButtonItems,定制导航栏返回按钮
    Apple Mach-O Linker (id) Error "_OBJC_CLASS...错误解决办法 Apple Mach-O Linker (id) Error "_OBJC_CLASS...错误解决办法
    Unrecognized Selector Sent to Instance问题之诱敌深入关门打狗解决办法
    UNRECOGNIZED SELECTOR SENT TO INSTANCE 问题快速定位的方法
    Present ViewController,模态详解
    UILABEL AUTOLAYOUT自动换行 版本区别
    iOS自动布局解决警告Automatic Preferred Max Layout Width is not available on iOS versions prior to 8.0
  • 原文地址:https://www.cnblogs.com/ShenJunHui6/p/10905048.html
Copyright © 2011-2022 走看看