• 【Django】REST_Framework框架——视图集ViewSet和ModelViewSet源码解析


    在这里插入图片描述


    一、ViewSet

    继承APIView和ViewSetMixin;
    作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。
    ViewSet在开发接口中不经常用

    1、ViewSet源码

    在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。

    class ViewSet(ViewSetMixin, views.APIView):
        """
        The base ViewSet class does not provide any actions by default.
        """
        pass
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    ViewSet视图集类不再限制视图方法名只允许get()、post()等这种情况了,而是实现允许开发者根据自己的需要定义自定义方法名,例如 list() 、create() 等,然后经过路由中使用http和这些视图方法名进行绑定调用

    2、ViewSetMixin源码

    ViewSet主要通过继承ViewSetMixin来实现在调用as_view()时传入字典{“http请求”:“视图方法”}的映射处理工作,如
    {‘get’:’list’,
    ‘post’:‘create’,
    ‘put’:‘update’,
    ‘delete’:‘destory’},

    在这里插入图片描述

    	@classonlymethod
        def as_view(cls, actions=None, **initkwargs):
            """
            Because of the way class based views create a closure around the
            instantiated view, we need to totally reimplement `.as_view`,
            and slightly modify the view function that is created and returned.
            """
            # The name and description initkwargs may be explicitly overridden for
            # certain route configurations. eg, names of extra actions.
            cls.name = None
            cls.description = None
    
            # The suffix initkwarg is reserved for displaying the viewset type.
            # This initkwarg should have no effect if the name is provided.
            # eg. 'List' or 'Instance'.
            cls.suffix = None
    
            # The detail initkwarg is reserved for introspecting the viewset type.
            cls.detail = None
    
            # Setting a basename allows a view to reverse its action urls. This
            # value is provided by the router through the initkwargs.
            cls.basename = None
    
            # actions must not be empty
            if not actions:
                raise TypeError("The `actions` argument must be provided when "
                                "calling `.as_view()` on a ViewSet. For example "
                                "`.as_view({'get': 'list'})`")
    
            # sanitize keyword arguments
            for key in initkwargs:
                if key in cls.http_method_names:
                    raise TypeError("You tried to pass in the %s method name as a "
                                    "keyword argument to %s(). Don't do that."
                                    % (key, cls.__name__))
                if not hasattr(cls, key):
                    raise TypeError("%s() received an invalid keyword %r" % (
                        cls.__name__, key))
    
            # name and suffix are mutually exclusive
            if 'name' in initkwargs and 'suffix' in initkwargs:
                raise TypeError("%s() received both `name` and `suffix`, which are "
                                "mutually exclusive arguments." % (cls.__name__))
    
            def view(request, *args, **kwargs):
                self = cls(**initkwargs)
    
                if 'get' in actions and 'head' not in actions:
                    actions['head'] = actions['get']
    
                # We also store the mapping of request methods to actions,
                # so that we can later set the action attribute.
                # eg. `self.action = 'list'` on an incoming GET request.
                self.action_map = actions
    
                # Bind methods to actions
                # This is the bit that's different to a standard view
                for method, action in actions.items():
                    handler = getattr(self, action)
                    setattr(self, method, handler)
    
                self.request = request
                self.args = args
                self.kwargs = kwargs
    
                # And continue as usual
                return self.dispatch(request, *args, **kwargs)
    
            # take name and docstring from class
            update_wrapper(view, cls, updated=())
    
            # and possible attributes set by decorators
            # like csrf_exempt from dispatch
            update_wrapper(view, cls.dispatch, assigned=())
    
            # We need to set these on the view function, so that breadcrumb
            # generation can pick out these bits of information from a
            # resolved URL.
            view.cls = cls
            view.initkwargs = initkwargs
            view.actions = actions
            return csrf_exempt(view)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83

    二、ModelViewSet

    使用ViewSet通常并不方便,因为list、retrieve、create、update、destory等action
    方法都需要自己编写,而这些方法与前面讲过的Mixin扩展类提供的方法同名,所以我们可以通过继承Mixin扩展类来复用这些方法而无需自己编写。

    ModelViewSet继承自 GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。

    1、ModelViewSet源码

    class ModelViewSet(mixins.CreateModelMixin,
                       mixins.RetrieveModelMixin,
                       mixins.UpdateModelMixin,
                       mixins.DestroyModelMixin,
                       mixins.ListModelMixin,
                       GenericViewSet):
        """
        A viewset that provides default `create()`, `retrieve()`, `update()`,
        `partial_update()`, `destroy()` and `list()` actions.
        """
        pass
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    三、ReadOnlyModelViewSet

    ReadOnlyModelViewSet承自 GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin。

    1、ReadOnlyModelViewSet源码

    class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
                               mixins.ListModelMixin,
                               GenericViewSet):
        """
        A viewset that provides default `list()` and `retrieve()` actions.
        """
        pass
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    四、GenericViewSet

    GenericViewSet继承ViewSetMixin、GenericAPIView
    继承ViewSetMixin:实现了在调用as_view()时传入字典{“http请求”:“视图方法”}的映射处理工作,如
    {‘get’:’list’,
    ‘post’:‘create’,
    ‘put’:‘update’,
    ‘delete’:‘destory’},
    继承了GenericAPIView:实现了分页、限流、过滤功能

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

  • 相关阅读:
    数据分析 -- numpy
    hosts文件的使用以及修改
    惠普服务器硬盘指示灯不亮或显示蓝色
    全国青少年软件编程等级考试标准(正式级)
    乾坤js隔离
    MySQL递归查询
    项目管理之八大绩效域------笔记(五)
    IP-guard助力能源企业完善终端防泄密措施,保护机密资料安全
    JS defineProperty详解
    docker概念、安装与卸载
  • 原文地址:https://blog.csdn.net/YZL40514131/article/details/126598807