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

9个视图子类

2个视图基类  
	APIView 
    GenericAPIView

5个视图扩展类
	DestroyModelMixin
    RetrieveModelMixin
    ListModelMixin
    CreateModelMixin
    UpdateModelMixin

9个视图子类 视图类 不需要额外继承不需要额外继承GenericAPIView 只需要继承9个中其中某个 就会有某个或某几个接口
	DestroyAPIView
    RetrieveAPIView
    RetrieveDestroyAPIView
    RetrieveUpdateAPIView
    RetrieveUpdateDestroyAPIView
    ListAPIView
    ListCreateAPIView
    CreateAPIView
    UpdateAPIView

第四层:高级

views.py

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个接口

from rest_framework.viewsets import ModelViewSet

第五层:高高级

url.py

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

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

image

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

2.通过ReadOnlyModelViewSet编写只读接口

只读:查询所有 查询单个

views.py

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

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

urlpatterns = [
    path('books/',views.BooksViews.as_view({'get': 'list'})),
    path('books/<int:pk>/',views.BooksViews.as_view({'get': 'retrieve'})),
ModelViewSet = mixins.CreateModelMixin+RetrieveModelMixin+UpdateModelMixin+DestroyModelMixin+ListModelMixin+GenericViewSet


GenericviewSet = ViewSetMixin+GenericAPIView

导致路由变了的原因就是ViewSetMixin【没见过的】
	

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

image

3.ViewSetMixin源码分析

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

image

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

image

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

@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包下的类

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

5.视图层大总结

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.自动生成路由

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

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

使用步骤:
	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))

底层实现:自动生成路由

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

action装饰器

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 @ 2023-02-06 21:47  李李大冒险  阅读(23)  评论(0编辑  收藏  举报
  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.

作词 : 周有才

作曲 : 周有才

这是一首简单的歌

没有什么独特

试着代入我的心事

它那么幼稚

像个顽皮的孩子

多么可笑的心事

只剩我还在坚持

谁能看透我的眼睛

让我能够不再失明

我要记住你的样子

像鱼记住水的拥抱

像云在天空中停靠

夜晚的来到

也不会忘了阳光的温暖

我要忘了你的样子

像鱼忘了海的味道

放下所有梦和烦恼

却放不下回忆的乞讨

多么可笑的心事

只剩我还在坚持

谁能看透我的眼睛

让我能够不再失明

记住你的样子

像鱼记住水的拥抱

像云在天空中停靠

夜晚的来到

也不会忘了阳光的温暖

我要忘了你的样子

像鱼忘了海的味道

放下所有梦和烦恼

却放不下回忆的乞讨

只剩自己就好