DRF(九)中的视图具体有哪些应用场景?

2026-05-17 08:231阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1083个文字,预计阅读时间需要5分钟。

DRF(九)- 视图+说明:DRF的开发一般使用CBV进行开发,Django的原生视图类是View类,DRF中使用较普遍的是APIView。1.GenericAPIView:该类继承自APIView,只封装了一些调用方法,完成了我需要的功能。

drf(九)—视图

说明:drf 的开发一般使用 CBV 进行开发,Django 的原生视图类是 View 类,drf 中使用较普通的是APIView

1.GenericAPIView

该类继承于APIView,只是封装了一些调用方法,完成我们的常用操作。

使用方式

class View1View(GenericAPIView): queryset = models.Role.objects serializer_class = RoleSerializers pagination_class = PageNumberPagination def get(self, request, *args, **kwargs): roles=self.get_queryset() # 获取到数据库中的数据 pager_roles=self.paginate_queryset(roles) ser=self.get_serializer(instance=pager_roles,many=True) return Response(ser.data)

使用 Pycharm 查看类的继承关系

说明:本类使用较少不做过多解释。

2.GenericViewSet

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 优先级高于后面的 GenericAPIView 类,多继承的顺序问题。

因此我们也可以在自定义的视图中直接继承这两个类。

class View2View(GenericViewSet): def get(self,rewuest,*args,**kwargs): return Response("....")

函数as_view()报错,缺少参数,进行修改;

此时,视图的不同已经开始影响了路由系统。

re_path('^api/(?P<version>[v1|v2]+)/viewv2/',view.View2View.as_view({'get':'list'})),

class View2View(GenericViewSet): def list(self,rewuest,*args,**kwargs): return Response("....")

修改后并将该方法的名称映射为字典的值。

进行源码剖析查看为何要这样传参。

class ViewSetMixin: @classonlymethod def as_view(cls, actions=None, **initkwargs): cls.name = None cls.description = None cls.suffix = None cls.detail = None cls.basename = None if not actions: raise TypeError("The `actions` argument must be provided when " "calling `.as_view()` on a ViewSet. For example " "`.as_view({'get': 'list'})`") 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)) 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'] self.action_map = actions for method, action in actions.items(): handler = getattr(self, action) # 使用反射进行方法。 setattr(self, method, handler) self.request = request self.args = args self.kwargs = kwargs return self.dispatch(request, *args, **kwargs) update_wrapper(view, cls, updated=()) update_wrapper(view, cls.dispatch, assigned=()) view.cls = cls view.initkwargs = initkwargs view.actions = actions return csrf_exempt(view) # 使得函数通过CSRF_TOKEN 3.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

列表类

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) # 改类帮我们写了list方法,我们不需要在进行编写

其他的类相同。

class View3View(ListModelMixin,GenericViewSet):# 只有查的功能 queryset = models.Role.objects.all() serializer_class = RoleSerializers pagination_class = PageNumberPagination

因此只要继承 ModelViewSet 可以直接获得增删改查的方法。

传入需要更新的视图或者查询单条记录的时候使用路由进行传参

总结
  1. 继承的越多,自己写的代码就越少;

  2. 影响路由系统,一个 url 会写两个路由;

  3. 使用建议

    1. 当对某张表需要具备增删改查的所有操作时使用 ModelViewSet,较好

    2. 当只实现某项功能的时候可以去单独执行某项 XXXModelMixin;

      总结: a.增删改查 ModelViewSet b.增删 CreateModelMixin,DestroyModelMixin GenericViewSet c.复杂逻辑 GenericViewSet 或 APIView

    3. 当业务功能较为复杂的时候使用APIView

补充:

视图的完整继承类图

标签:开发

本文共计1083个文字,预计阅读时间需要5分钟。

DRF(九)- 视图+说明:DRF的开发一般使用CBV进行开发,Django的原生视图类是View类,DRF中使用较普遍的是APIView。1.GenericAPIView:该类继承自APIView,只封装了一些调用方法,完成了我需要的功能。

drf(九)—视图

说明:drf 的开发一般使用 CBV 进行开发,Django 的原生视图类是 View 类,drf 中使用较普通的是APIView

1.GenericAPIView

该类继承于APIView,只是封装了一些调用方法,完成我们的常用操作。

使用方式

class View1View(GenericAPIView): queryset = models.Role.objects serializer_class = RoleSerializers pagination_class = PageNumberPagination def get(self, request, *args, **kwargs): roles=self.get_queryset() # 获取到数据库中的数据 pager_roles=self.paginate_queryset(roles) ser=self.get_serializer(instance=pager_roles,many=True) return Response(ser.data)

使用 Pycharm 查看类的继承关系

说明:本类使用较少不做过多解释。

2.GenericViewSet

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 优先级高于后面的 GenericAPIView 类,多继承的顺序问题。

因此我们也可以在自定义的视图中直接继承这两个类。

class View2View(GenericViewSet): def get(self,rewuest,*args,**kwargs): return Response("....")

函数as_view()报错,缺少参数,进行修改;

此时,视图的不同已经开始影响了路由系统。

re_path('^api/(?P<version>[v1|v2]+)/viewv2/',view.View2View.as_view({'get':'list'})),

class View2View(GenericViewSet): def list(self,rewuest,*args,**kwargs): return Response("....")

修改后并将该方法的名称映射为字典的值。

进行源码剖析查看为何要这样传参。

class ViewSetMixin: @classonlymethod def as_view(cls, actions=None, **initkwargs): cls.name = None cls.description = None cls.suffix = None cls.detail = None cls.basename = None if not actions: raise TypeError("The `actions` argument must be provided when " "calling `.as_view()` on a ViewSet. For example " "`.as_view({'get': 'list'})`") 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)) 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'] self.action_map = actions for method, action in actions.items(): handler = getattr(self, action) # 使用反射进行方法。 setattr(self, method, handler) self.request = request self.args = args self.kwargs = kwargs return self.dispatch(request, *args, **kwargs) update_wrapper(view, cls, updated=()) update_wrapper(view, cls.dispatch, assigned=()) view.cls = cls view.initkwargs = initkwargs view.actions = actions return csrf_exempt(view) # 使得函数通过CSRF_TOKEN 3.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

列表类

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) # 改类帮我们写了list方法,我们不需要在进行编写

其他的类相同。

class View3View(ListModelMixin,GenericViewSet):# 只有查的功能 queryset = models.Role.objects.all() serializer_class = RoleSerializers pagination_class = PageNumberPagination

因此只要继承 ModelViewSet 可以直接获得增删改查的方法。

传入需要更新的视图或者查询单条记录的时候使用路由进行传参

总结
  1. 继承的越多,自己写的代码就越少;

  2. 影响路由系统,一个 url 会写两个路由;

  3. 使用建议

    1. 当对某张表需要具备增删改查的所有操作时使用 ModelViewSet,较好

    2. 当只实现某项功能的时候可以去单独执行某项 XXXModelMixin;

      总结: a.增删改查 ModelViewSet b.增删 CreateModelMixin,DestroyModelMixin GenericViewSet c.复杂逻辑 GenericViewSet 或 APIView

    3. 当业务功能较为复杂的时候使用APIView

补充:

视图的完整继承类图

标签:开发