CodeYarn青鸟川中青鸟

9个视图子类、视图集、路由系统

Toretto·2023-02-06 21:47·28 次阅读

9个视图子类、视图集、路由系统

9个视图子类#

Copy
2个视图基类 APIView GenericAPIView 5个视图扩展类 DestroyModelMixin RetrieveModelMixin ListModelMixin CreateModelMixin UpdateModelMixin 9个视图子类 视图类 不需要额外继承不需要额外继承GenericAPIView 只需要继承9个中其中某个 就会有某个或某几个接口 DestroyAPIView RetrieveAPIView RetrieveDestroyAPIView RetrieveUpdateAPIView RetrieveUpdateDestroyAPIView ListAPIView ListCreateAPIView CreateAPIView UpdateAPIView

第四层:高级

views.py

Copy
class BooksViews(ListCreateAPIView): queryset= Books serializer_class=BookSerializers class BookViews(RetrieveUpdateDestroyAPIView): queryset= Books serializer_class=BookSerializers

image

ListCreateAPIView 里面写好了 get 和post 不需要单独在写

image

同样 RetrieveUpdateDestroyAPIView里面也封装了一些方法

视图集#

1.通过ModelViewSet编写5个接口#

Copy
from rest_framework.viewsets import ModelViewSet

第五层:高高级

url.py

Copy
urlpatterns = [ path('admin/', admin.site.urls), path('books/',views.BooksViews.as_view({'get': 'list', 'post': 'create'})), path('books/<int:pk>/',views.BooksViews.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})), ]

views.py

Copy
class BooksViews(ModelViewSet): queryset= Books.objects.all() serializer_class=BookSerializers

image

ModelViewSet里面已经写好了方法 直接用就可以 但是需要重写路由 路由格式变成 as_view({'k': 'v'}) 这样的格式

2.通过ReadOnlyModelViewSet编写只读接口#

只读:查询所有 查询单个

views.py

Copy
class BooksViews(ReadOnlyModelViewSet): queryset= Books.objects.all() serializer_class=BookSerializers

url.py as_view括号里面的请求参数 只能填查询所有 和查询单个的 写多了会报错

Copy
urlpatterns = [ path('books/',views.BooksViews.as_view({'get': 'list'})), path('books/<int:pk>/',views.BooksViews.as_view({'get': 'retrieve'})),
Copy
ModelViewSet = mixins.CreateModelMixin+RetrieveModelMixin+UpdateModelMixin+DestroyModelMixin+ListModelMixin+GenericViewSet GenericviewSet = ViewSetMixin+GenericAPIView 导致路由变了的原因就是ViewSetMixin【没见过的】

ViewSetMixin源码注释:以后配置路由变成了view = MyViewSet.as_view({'get': 'list', 'post': 'create'})这种形式

image

3.ViewSetMixin源码分析#

Copy
请求来 -- 路由匹配成功 get请求 -- 匹配成功 books会执行 -- views.BooksViews.as_view({'get': 'list'}) 读as_view 这个as_view是ViewSetMixin的as_view

image

上面的方法都没有 去GenericviewSet里面找

image

ViewSetMixin在前面 先去这里面找 找到了

Copy
@classonlymethod def as_view(cls, actions=None, **initkwargs): if not actions: raise TypeError("The `actions` argument must be provided when " "calling `.as_view()` on a ViewSet. For example " "`.as_view({'get': 'list'})`") #如果没有传actions直接抛异常 路由的as_view中不传字典 直接报错 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) return csrf_exempt(view) #去除了csrf校验 #路由匹配成功执行views.BooksViews.as_view({'get': 'retrieve'})), #本质是执行viewSetMixin -- as_view -- view() def view(request, *args, **kwargs): self.action_map = actions #actions是传入的字典{'get': 'retrieve'} for method, action in actions.items(): #第一次循环:method:get action:retrieve handler = getattr(self, action) #通过反射去视图类中反射action对应的方法 setattr(self, method, handler) #把method:get请求方法 handler:list方法 #视图类的对象的get方法 变成list方法 self.request = request self.args = args self.kwargs = kwargs return self.dispatch(request, *args, **kwargs) #dispatch 是APIView的

总结:#

​ 1.只要继承ViewSetMixin的视图类 路由写法就变了(重写了as_view)

​ 2.路由变成需要传入地点的映射方法

​ 只要传入actions 以后访问get就是访问list以此类推

​ 3.其他一样

​ 4.以后视图类中的方法名可以任意命名 只要做好映射就可以

4.from rest_framework.viewsets包下的类#

Copy
ModelViewSet: 5个视图扩展类+ViewSetMixin + GenericAPIView ReadOnlyModelViewSet: 2个视图扩展类 (读全部 读单个+ViewSetMixin+GenericAPIView ViewSetMixin: 魔法 重写了as_view只要继承他 路由就变成字典映射方法 ViewSet: ViewSetMixin+ APIView GenericViewSet: ViewSetMixin+ GenericAPIView #重点: 以后像继承APIView但是想变路由写法 (视图类中方法名任意命名)要继承ViewSet 在里面写方法 以后想要继承GenericAPIView 但是想变路由写法(视图类中方法名任意命名) 要继承GenericViewSet 在里面写方法

5.视图层大总结#

Copy
1.两个视图基类 APIView GenericAPIView 2.5个试图扩展类 不是视图类 必须配合GenericAPIView一起使用 from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin 3.9个试图子类 是视图类 用到哪个继承那个就可以 from rest_framework.generics import DestroyAPIView RetrieveAPIView RetrieveDestroyAPIView RetrieveUpdateAPIView RetrieveUpdateDestroyAPIView ListAPIView ListCreateAPIView CreateAPIView UpdateAPIView 4.视图集 ModelViewSet: 路由写法变了 字典、映射方法 只需要写两行 5个接口都能用 ReadOnlyModelViewSet: 路由写法变了,字典、映射方法(只写两个actions 查所有和查一个) 只需要写两行,2个只读接口都有了 ViewSetMixin: 不是视图类 重写了as_view 路由写法变了 变成映射 ViewSet: ViewSetMixin+ APIView GenericViewSet: ViewSetMixin+ GenericAPIView # 举例子:发送短信接口,视图类叫SendView,方法叫send_sms,路由配置变了 get--->send_sms class SendView(ViewSet): def send_sms(self,request):

image

路由系统#

1.自动生成路由#

Copy
# drf 由于继承ViewSetMinxin类,路由写法变了 -原生+drf,以后的路由写法,可能会有如下情况(三种情况) -path('books/', views.BookView.as_view() -path('books/', views.BookView.as_view({'get': 'list', 'post': 'create'})) -自动生成

drf提供了两个路由类,继承ModelViewSet后,路由可以自动生成

Copy
使用步骤: 1.导入路由类 from rest_framework.routers import SimpleRouter,DefaultRouter 2.实例化的到一个对象 router = SimpleRouter() 少 常用 router = DefaultRouter()多 3.注册 router.register('books',views.Bookviews,'books') 4.在urlpatterns中注册 两种方式 方式1: urlpatterns += router.url 方式2: include:path(api/v1/,include(router.url))

底层实现:自动生成路由

Copy
本质是自动做映射 能够自动成的前提是 视图类中要有5个方法的某个甚至更多 get--->list get---->retrieve put---->update post---->create delete---->destory ModelViewSet和ReadOnlyModelViewSet: 可以自动生成路由 9个视图子类+ViewSetMixin: 才可以自动生成 GenericAPIView+5个试图扩展类+ViewSetMixin: 才能自动生成

action装饰器#

Copy
action 写在视图类的方法上 可以自动生成路由 使用步骤: 1.写在视图类方法上 class BooksViews(ModelViewSet): @action(methods=['GET'], detail=False, url_name='send', url_path='send') #method指定请求方法 可以传多个 #deatil 只能传: #True:带id的路径 :send/2/send_sms/ #Flase:不带id的路径::send/send_sms/ def send(self,request): return Response('123') '以后看到drf路由写法 后期都是自动生成 一般不在urlpatterns加入路由' 补充: 1.不同请求方式可以使用不同的序列化类 2.不同的action使用不同的序列化类 class SendView(GenericViewSet): queryset = None serializer_class = '序列化类' def get_serializer(self, *args, **kwargs): if self.action=='lqz': return '某个序列化类' else: return '另一个序列化列' @action(methods=['GET'], detail=True) def send_sms(self, request,pk): print(pk) # 手机号,从哪去,假设get请求,携带了参数 phone = request.query_params.get('phone') print('发送成功,%s' % phone) return Response({'code': 100, 'msg': '发送成功'}) @action(methods=['GET'], detail=True) def lqz(self,request): # get # 序列化类 pass @action(methods=['GET'], detail=True) def login(self,request): # get # 序列化类 pass
posted @   李李大冒险  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
  1. 1 不可撤销
  2. 2 小年兽 程嘉敏
  3. 3 迷人的危险3 FAFA
  4. 4 山楂树之恋 程佳佳
  5. 5 summertime cinnamons / evening cinema
  6. 6 不谓侠(Cover 萧忆情Alex) CRITTY
  7. 7 神武醉相思(翻自 优我女团) 双笙(陈元汐)
  8. 8 空山新雨后 音阙诗听 / 锦零
  9. 9 Wonderful U (Demo Version) AGA
  10. 10 广寒宫 丸子呦
  11. 11 陪我看日出 回音哥
  12. 12 春夏秋冬的你 王宇良
  13. 13 世界が终わるまでは… WANDS
  14. 14 多想在平庸的生活拥抱你 隔壁老樊
  15. 15 千禧 徐秉龙
  16. 16 我的一个道姑朋友 双笙(陈元汐)
  17. 17 大鱼 (Cover 周深) 双笙(陈元汐)
  18. 18 霜雪千年(Cover 洛天依 / 乐正绫) 双笙(陈元汐) / 封茗囧菌
  19. 19 云烟成雨(翻自 房东的猫) 周玥
  20. 20 情深深雨濛濛 杨胖雨
  21. 21 Five Hundred Miles Justin Timberlake / Carey Mulligan / Stark Sands
  22. 22 斑马斑马 房东的猫
  23. 23 See You Again Wiz Khalifa / Charlie Puth
  24. 24 Faded Alan Walker
  25. 25 Natural J.Fla
  26. 26 New Soul Vox Angeli
  27. 27 ハレハレヤ(朗朗晴天)(翻自 v flower) 猫瑾
  28. 28 像鱼 王贰浪
  29. 29 Bye Bye Bye Lovestoned
  30. 30 Blame You 眠 / Lopu$
  31. 31 Believer J.Fla
  32. 32 书信 戴羽彤
  33. 33 柴 鱼 の c a l l i n g【已售】 幸子小姐拜托了
  34. 34 夜空中最亮的星(翻自 逃跑计划) 戴羽彤
  35. 35 慢慢喜欢你 LIve版 戴羽彤
  36. 36 病变 戴羽彤
  37. 37 那女孩对我说 (完整版) Uu
  38. 38 绿色 陈雪凝
  39. 39 月牙湾 LIve版 戴羽彤
像鱼 - 王贰浪
00:00 / 04:45
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 周有才

作曲 : 周有才

这是一首简单的歌

没有什么独特

试着代入我的心事

它那么幼稚

像个顽皮的孩子

多么可笑的心事

只剩我还在坚持

谁能看透我的眼睛

让我能够不再失明

我要记住你的样子

像鱼记住水的拥抱

像云在天空中停靠

夜晚的来到

也不会忘了阳光的温暖

我要忘了你的样子

像鱼忘了海的味道

放下所有梦和烦恼

却放不下回忆的乞讨

多么可笑的心事

只剩我还在坚持

谁能看透我的眼睛

让我能够不再失明

记住你的样子

像鱼记住水的拥抱

像云在天空中停靠

夜晚的来到

也不会忘了阳光的温暖

我要忘了你的样子

像鱼忘了海的味道

放下所有梦和烦恼

却放不下回忆的乞讨

只剩自己就好

点击右上角即可分享
微信分享提示
目录