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
            })
  • 相关阅读:
    用智慧明辨之
    做一个成功的软件架构师需要哪些素质?
    如何成为一名优秀的产品经理
    项目管理中的冲突管理
    .Net 缓存依赖详解
    从程序制作到构架制作
    如何做好一名软件团队的领导者
    需求变更的代价
    页面缓存的实现
    项目风险盘点
  • 原文地址:https://www.cnblogs.com/ShenJunHui6/p/10905048.html
Copyright © 2011-2022 走看看