drf篇:rest_framework视图组件、路由自动生成及action装饰器

rest_framework视图组件、路由自动生成及action装饰器

一、视图层

2个视图基类

复制代码
  • 1
  • 2
# django 内置的View # drf 的APIView ,继承自View

第一层:使用APIView写5个接口

复制代码
  • 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
from rest_framework.views import APIView from rest_framework.generics import GenericAPIView from .models import Book from .serializer import BookSerializer from rest_framework.response import Response class BookView(APIView): def get(self,request): book_list=Book.objects.all() # 如果写了many=True,ser是哪个类的对象? ser=BookSerializer(instance=book_list,many=True) print(type(ser)) # ListSerializer的对象---》[BookSerializer,BookSerializer,BookSerializer] return Response(ser.data) def post(self,request): ser=BookSerializer(data=request.data) if ser.is_valid(): ser.save() return Response({'code':'100','msg':'创建成功'}) else: return Response({'code': '101', 'msg': '创建失败','err':ser.errors}) class BookDetailView(APIView): def get(self,request,*args,**kwargs): # pk 从kwargs中去 book=Book.objects.filter(pk=kwargs['pk']).first() # 如果写了many=True,ser是哪个类的对象? ser=BookSerializer(instance=book) print(type(ser)) # BookSerializer的对象 return Response(ser.data) #put:全局修改 patch:局部修改 def put(self,request,*args,**kwargs): # pk 从kwargs中去 book=Book.objects.filter(pk=kwargs['pk']).first() ser=BookSerializer(instance=book,data=request.data) if ser.is_valid(): ser.save() return Response({'code': '100', 'msg': '创建成功'}) else: return Response({'code': '101', 'msg': '创建失败', 'err': ser.errors})

第二层:继承GenericAPIView写5个接口

复制代码
  • 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
""" -两个重要的类属性: queryset = Book.objects.all() # 要序列化的数据 serializer_class = BookSerializer # 序列化类 -几个重要的方法: self.get_object() self.get_queryset() self.get_serializer(instance=book_list, many=True) """ class BookView(GenericAPIView): queryset = Book.objects.all() # 要序列化的数据 serializer_class = BookSerializer # 序列化类 def get(self, request): book_list = self.get_queryset() # 获取要序列化的数据,不要直接使用self.queryset,而要用self.get_queryset() # 获取序列化类,要使用self.get_serializer ser = self.get_serializer(instance=book_list, many=True) print(type(ser)) # ListSerializer的对象---》[BookSerializer,BookSerializer,BookSerializer] return Response(ser.data) def post(self, request): ser = self.get_serializer(data=request.data) if ser.is_valid(): ser.save() return Response({'code': '100', 'msg': '创建成功'}) else: return Response({'code': '101', 'msg': '创建失败', 'err': ser.errors}) class BookDetailView(GenericAPIView): queryset = Book.objects.all() # 要序列化的数据 serializer_class = BookSerializer # 序列化类 #传入的必须叫pk,否则,get_object就拿不到对象 def get(self, request, *args, **kwargs): # 获取单个对象, book = self.get_object() # 如果写了many=True,ser是哪个类的对象? ser = self.get_serializer(instance=book) print(type(ser)) # BookSerializer的对象 return Response(ser.data) # put:全局修改 patch:局部修改 def put(self, request, *args, **kwargs): # pk 从kwargs中去 book = self.get_object() ser = self.get_serializer(instance=book, data=request.data) if ser.is_valid(): ser.save() return Response({'code': '100', 'msg': '创建成功'}) else: return Response({'code': '101', 'msg': '创建失败', 'err': ser.errors})

第三层:继承GenericAPIView+5个视图扩展类实现5个接口

5 个视图扩展类

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
# 视图扩展类---》不是视图类---》没有继承视图类(View,APIView...子类) ListModelMixin, # 获取所有 CreateModelMixin, # 创建一个 RetrieveModelMixin, # 查询一个 UpdateModelMixin, # 更新一个 DestroyModelMixin # 删除一个
复制代码
  • 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
# class ListModeMixin(): # def list(self, request): # print('dsafdasdfasd') # book_list = self.get_queryset() # 获取要序列化的数据,不要直接使用self.queryset,而要用self.get_queryset() # # # 获取序列化类,要使用self.get_serializer # ser = self.get_serializer(instance=book_list, many=True) # print(type(ser)) # ListSerializer的对象---》[BookSerializer,BookSerializer,BookSerializer] # return Response(ser.data) from rest_framework.mixins import ListModelMixin,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin class BookView(GenericAPIView,ListModelMixin,CreateModelMixin): queryset = Book.objects.all() # 要序列化的数据 serializer_class = BookSerializer # 序列化类 def get(self,request): print('获取所有') return super().list(request) def post(self, request): return super().create(request) class BookDetailView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin): queryset = Book.objects.all() # 要序列化的数据 serializer_class = BookSerializer # 序列化类 #传入的必须叫pk,否则,get_object就拿不到对象 def get(self, request, *args, **kwargs): print('获取一') return super().retrieve(request, *args, **kwargs) # put:全局修改 patch:局部修改 def put(self, request, *args, **kwargs): # pk 从kwargs中去 return super().update(request, *args, **kwargs) def delete(self,request, *args, **kwargs): return super().destroy(request, *args, **kwargs)

第四层:9个视图子类

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
5个视图拓展类而来 # 获取所有,新增一个,获取所有和新建一个 ListAPIView,CreateAPIView,ListCreateAPIView # 获取单个,更新一个,删除一个 RetrieveAPIView,UpdateAPIView,DestroyAPIView # RetrieveUpdateDestroyAPIView,RetrieveUpdateAPIView,RetrieveDestroyAPIView # 继承9个视图子类后,只需要在视图类中写两个类属性即可
复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
from rest_framework.generics import ListAPIView,CreateAPIView,ListCreateAPIView from rest_framework.generics import RetrieveAPIView,UpdateAPIView,DestroyAPIView from rest_framework.generics import RetrieveUpdateDestroyAPIView,RetrieveUpdateAPIView,RetrieveDestroyAPIView class BookView(ListCreateAPIView): # 获取所有和新增一个 queryset = Book.objects.all() # 要序列化的数据 serializer_class = BookSerializer # 序列化类 class BookDetailView(RetrieveUpdateDestroyAPIView): queryset = Book.objects.all() # 要序列化的数据 serializer_class = BookSerializer # 序列化类

第五层:视图集

复制代码
  • 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
ModelViewSet= # 5个视图扩展类---》每个类里有一个方法 list,create,retrieve,destory,update mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, # ViewSetMixin:特点,只要继承它,路由写法变了,变成了:as_view({'get': 'list', 'post': 'create'}---》请求方式和方法的对应关系 # generics.GenericAPIView 2个视图基类中得一个 GenericViewSet -ViewSetMixin+GenericAPIView # ViewSetMixin 源码分析 class ViewSetMixin: @classonlymethod def as_view(cls, actions=None, **initkwargs): # actions={'get': 'list', 'post': 'create'} def view(request, *args, **kwargs): # method:get action:list for method, action in actions.items(): # handler就是list handler = getattr(self, action) #视图类反射有没有list # 反射:把get变成了list setattr(self, method, handler) return self.dispatch(request, *args, **kwargs) return csrf_exempt(view) # 如果请求来了,会执行 view(request)

视图集中的类

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
# 视图集中的类 -ModelViewSet -ReadOnlyModelViewSet -ViewSetMixin -ViewSet :ViewSetMixin+APIView -GenericViewSet:ViewSetMixin+GenericAPIView # 以后你想继承APIView,但是路由想自动生成,继承ViewSet # 以后想继承GenericViewSet,但是路由想自动生成,GenericViewSet

使用视图集写5个接口+修改路由格式

复制代码
  • 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
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet,ViewSetMixin,GenericViewSet,ViewSet # 1.ModelViewSet,支持所有请求方式,需要在路由写映射关系 """ path('books/',BookView.as_view({'get':'list','post':'create',})), path('books/<int:pk>',BookView.as_view({'get':'retrieve','put':'update','delete':'destroy'})), """ class BookView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer # 2.ReadOnlyModelViewSet,仅支持序列化操作,也需要写映射关系,但是只支持list和retrieve """ path('books/',BookView.as_view({'get':'list'})), path('books/<int:pk>',BookView.as_view({'get':'retrieve'})), """ class BookView(ReadOnlyModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer # GenericViewSet = ViewSetMixin + GenericAPIView # ViewSet = ViewSetMixin + APIView # 3.Viewset = ViewSetMixin + APIView from rest_framework.decorators import action class BookView(ViewSet): @action(methods=['post','get'],detail=False,url_path='as') def lvchenxi(self,request): print('大狗子') return Response({}) ''' action关键参数: methods:请求方式 detail: False:是不是带id的路由 http://127.0.0.1/publish/3 http://127.0.0.1/publish True: 生成的路由publish/pk/lqz/ url_path:如果不写,就是函数名生成的路径是:http://127.0.0.1/publish/lqz url_name:别名 '''

二、路由层

1、路由组件

复制代码
  • 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
# 1 继承了ViewSetMixin及其子类,路由写法变了 -写法一:path('publish', views.PublishView.as_view({'get': 'lqz','post':'login'})), -写法二:自动生成 # 第一步:导入一个路由类 from rest_framework.routers import SimpleRouter, DefaultRouter # 第二步:实例化得到对象 router=SimpleRouter() # router = DefaultRouter() # 它会给每个注册的视图类都生成一个根路由 # 第三步:注册路由---》使用视图类注册---》能自动生成路由 router.register('books', views.BookView, 'books') router.register('publish', views.BookView, 'publish') # 第四步:在总路由中注册 方式二 path('', include(router.urls)), # 第四步:在总路由中注册 方式一 # urlpatterns+=router.urls # action装饰器的用法 -之前自动生成路由只能生成 {'get': 'list', 'post': 'create'},{'get': 'retrieve', 'put': 'update', 'delete': 'destroy'} -使用action装饰器来做对应关系 ''' methods:请求方式 detail: False:是不是带id的路由 http://127.0.0.1/publish/3 http://127.0.0.1/publish True: 生成的路由publish/pk/lqz/ url_path:如果不写,就是函数名生成的路径是:http://127.0.0.1/publish/lqz url_name:别名 '''

2、 自己写路由,指定映射关系

复制代码
  • 1
path('publish', views.PublishView.as_view({'get': 'lqz','post':'login'})),

3、只要继承了ViewSetMixin,路由写法就变了,需要映射关系

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
class PublishView(ViewSetMixin,APIView): # 路由写法变了,变成映射关系了,在视图类中可以写任意的方法名 def lqz(self,request): return Response('lqz') def login(self,request): return Response('login')

XX3RMD.png

补充

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
1 # 浏览器输入地址 www.taobao.com----》dns(本地,网络)(host文件)查找 ip地址--》向这个地址的80端口发送请求(没写端口就是80) 2 序列化的时候,如果传了many=True,生成的序列化类对的对象是ListSerializer的对象 3 assert 断言 本质就是if+抛异常 a = 11 # if a!=10: # raise Exception('a必须是10,不然不能往后走') assert a == 10, ('a必须是10,不然不能往后走') print(a) 4 列表可以相加
posted @   马氵寿  阅读(193)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开