热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

drf(九)—视图

drf(九)—视图说明:drf的开发一般使用CBV进行开发,Django的原生视图类是View类,drf中使用较普通的是APIView。1.GenericAPIView该类继承于A

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 查看类的继承关系

image-20220411090234548

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


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 类,多继承的顺序问题。

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

image-20220411095442110

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

image-20220411100633111

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

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

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

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

image-20220411100935373

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

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

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

image-20220411134322275

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

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

image-20220411140121249


总结



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



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



  3. 使用建议



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



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

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


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





补充:

视图的完整继承类图

viewsets



推荐阅读
author-avatar
Henry-lau洋
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有