zoukankan      html  css  js  c++  java
  • django——rest_framework 视图与逻辑の使用详细分析

    django rest_framework 视图与逻辑の使用详细分析

    视图类

    django.views.generic.base.View

    实现了简单的路由分发,不同的method实现不同的方法

    rest_framewrok.views.APIView

    基于 django的View,又实现了用户认证,权限,限流,版本,解析器

    rest_framework.generic.GenericAPIView

    基于 rest_framewrok的APIView,又实现了分页过滤,分页,上下文处理,基础的数据集获取,单条数据获取

    这些都是基于django的View实现的视图功能,使用的时候,还是要自己写method对应的方法(get, post, delete.....)

    功能类

    rest_framework.mixins.py文件,实现了不同请求的逻辑处理

    CreateModelMixin

    创建

    class CreateModelMixin:
        """
        Create a model instance.
        """
        def create(self, request, *args, **kwargs):
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
    
        def perform_create(self, serializer):
            serializer.save()
    
        def get_success_headers(self, data):
            try:
                return {'Location': str(data[api_settings.URL_FIELD_NAME])}
            except (TypeError, KeyError):
                return {}
    

    ListModelMixin

    列表查询

    class ListModelMixin:
        """
        List a queryset.
        """
        def list(self, request, *args, **kwargs):
            queryset = self.filter_queryset(self.get_queryset())
    
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
    
            serializer = self.get_serializer(queryset, many=True)
            return Response(serializer.data)
    

    DestroyModelMixin

    删除

    class DestroyModelMixin:
        """
        Destroy a model instance.
        """
        def destroy(self, request, *args, **kwargs):
            instance = self.get_object()
            self.perform_destroy(instance)
            return Response(status=status.HTTP_204_NO_CONTENT)
    
        def perform_destroy(self, instance):
            instance.delete()
    

    RetrieveModelMixin

    详情页

    class RetrieveModelMixin:
        """
        Retrieve a model instance.
        """
        def retrieve(self, request, *args, **kwargs):
            instance = self.get_object()
            serializer = self.get_serializer(instance)
            return Response(serializer.data)
    

    UpdateModelMixin

    更新

    class UpdateModelMixin:
        """
        Update a model instance.
        """
        def update(self, request, *args, **kwargs):
            partial = kwargs.pop('partial', False)
            instance = self.get_object()
            serializer = self.get_serializer(instance, data=request.data, partial=partial)
            serializer.is_valid(raise_exception=True)
            self.perform_update(serializer)
    
            if getattr(instance, '_prefetched_objects_cache', None):
                # If 'prefetch_related' has been applied to a queryset, we need to
                # forcibly invalidate the prefetch cache on the instance.
                instance._prefetched_objects_cache = {}
    
            return Response(serializer.data)
    
        def perform_update(self, serializer):
            serializer.save()
    
        def partial_update(self, request, *args, **kwargs):
            kwargs['partial'] = True
            return self.update(request, *args, **kwargs)
    

    视图和功能的整合之自动匹配路由与方法

    现在有了逻辑处理,有了视图路由分发,但是视图功能最多的GenericAPIView,对应的路由分发,逻辑还是通过url请求方法反射对应的方法,无法和mixins中的增删改查对应上。
    所以,还有一个类,总和了GenericAPIView视图和mixins的各种方法:

    rest_framework.generics.ListCreateAPIView

    汇总了GenericAPIView视图,和ListModelMixin列表和CreateModelMixin创建

    class ListCreateAPIView(mixins.ListModelMixin,
                            mixins.CreateModelMixin,
                            GenericAPIView):
        """
        Concrete view for listing a queryset or creating a model instance.
        """
        def get(self, request, *args, **kwargs):
            return self.list(request, *args, **kwargs)
    
        def post(self, request, *args, **kwargs):
            return self.create(request, *args, **kwargs)
    
    • 如果不让创建的话,就是用ListAPIView
    class ListAPIView(mixins.ListModelMixin,
                      GenericAPIView):
        """
        Concrete view for listing a queryset.
        """
        def get(self, request, *args, **kwargs):
            return self.list(request, *args, **kwargs)
    

    rest_framework.generics.RetrieveUpdateDestroyAPIView

    GenericAPIView视图,RetrieveModelMixin数据详情,UpdateModelMixin数据更新,DestroyModelMixin数据删除
    class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
                                       mixins.UpdateModelMixin,
                                       mixins.DestroyModelMixin,
                                       GenericAPIView):
        """
        Concrete view for retrieving, updating or deleting a model instance.
        """
        def get(self, request, *args, **kwargs):
            return self.retrieve(request, *args, **kwargs)
    
        def put(self, request, *args, **kwargs):
            return self.update(request, *args, **kwargs)
    
        def patch(self, request, *args, **kwargs):
            return self.partial_update(request, *args, **kwargs)
    
        def delete(self, request, *args, **kwargs):
            return self.destroy(request, *args, **kwargs)
    

    有些功能不需要的,就取消对应功能的类,

    • DestroyAPIView只有删除
    • UpdateAPIView只能更新
    • RetrieveAPIView只有详情功能(不能删除和更新)
    • RetrieveUpdateAPIView只有详情和更新功能(不能删除)
    • RetrieveDestroyAPIView只有详情和删除功能(不能修改)

    视图和功能的整合之自定义匹配路由与方法

    rest_framework.viewsets.GenericViewSet

    GenericViewSet视图,ViewSetMixin,路由反射通过自定义实现

    class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
        """
        The GenericViewSet class does not provide any actions by default,
        but does include the base set of generic view behavior, such as
        the `get_object` and `get_queryset` methods.
        """
        pass
    

    看一下ViewSetMixin,as_view方法里面有一段是这样的

          @classonlymethod
          def as_view(cls, actions=None, **initkwargs):
                # .........
                for method, action in actions.items():
                    handler = getattr(self, action)
                    setattr(self, method, handler)
    
    # 就是,as_view里面传入字典格式,就可以自定义了
    view = MyViewSet.as_view({'get': 'list', 'post': 'create'})
    

    继承关系图

    ListCreateAPIView

    ListCreateAPIView

    RetrieveUpdateDestroyAPIView

    RetrieveUpdateDestroyAPIView

    GenericViewSet

    GenericViewSet

    创作不易,转载请注明出处和附带链接

  • 相关阅读:
    Linux使用lrzsz上传下载文件
    开发Wordpress主题时没有特色图片的功能
    Windows10重启之后总是将默认浏览器设置为IE
    C#泛型类的类型约束
    CentOS给网站配置Https证书
    从微软官网下载VS离线安装包的方法
    Azure Sql Database为某个数据库创建单独的访问账户
    VS2017/2019 Product Key
    VMware Workstation/Fusion 14/15 密钥
    将DataTable进行分页并生成新的DataTable
  • 原文地址:https://www.cnblogs.com/pywjh/p/14797033.html
Copyright © 2011-2022 走看看