drf 视图组件
- 视图基类
- 基于APIView写五个接口
- 基于GenericAPIView写5个接口
- 5个视图扩展类
- 9个视图子类
- 视图集
两个视图基类
-
视图的两个基类分别是
APIView : 继承django的View
GenericAPIView: 继承APIView
-
GenericAPIView:属性和方法
-
属性
1.重点掌握 ① queryset # 要序列化的数据 ② serializer_class # 序列化类 2.了解 lookup_field # 通过get_object 获取单个对象的查询key值,value值是路由中传进来的 filter_backends # 过滤类 pagination_class # 分页类
-
方法
1.重点掌握 get_queryset # 获取要序列化的数据 get_object # 根据lookup_field配置的参数获取单个对象 get_serializer # 获取序列化类,咱们直接用的 get_serializer_class # 获取序列化类,不是咱们直接用的get_serializer调用了它 2.了解 filter_queryset # 跟过滤有关系 paginate_xxx # 跟分页有关
-
基于APIView写5个接口
class UserView(APIView): def get(self, request): res_list = User.objects.all() ser = UserSerializer(instance=res_list, many=True) return Response(ser.data) def post(self, request): ser = UserSerializer(data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': "新增成功"}, status=201) else: return Response({'code': 101, 'msg': ser.errors}) class UserDetailView(APIView): def get(self, request, pk): obj = User.objects.filter(pk=pk).first() ser = UserSerializer(instance=obj) return Response(ser.data) def put(self, request, pk): obj = User.objects.filter(pk=pk).first() ser = UserSerializer(instance=obj, data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': "修改成功"}, status=201) else: return Response({'code': 101, 'msg': ser.errors}) def delete(self, request, pk): User.objects.filter(pk=pk).delete() return Response('')
基于GenericAPIView写5个接口
class UserView(GenericAPIView): # 配置两个 类属性 queryset = User.objects.all() serializer_class = UserSerializer # def get_queryset(self): # if self.request.method=='GET': # return User.objects.all() # else: # return Publish.object.all() def get(self, request): res_list = self.get_queryset() # 提高扩展性 ser = self.get_serializer(instance=res_list, many=True) 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': "新增成功"}, status=201) else: return Response({'code': 101, 'msg': ser.errors}) class UserDetailView(GenericAPIView): queryset = User.objects.all() serializer_class = UserSerializer def get(self, request, pk): # obj = self.get_queryset().filter(pk=pk).first() # queryset.get({'pk':'有名分组分出来的'} obj = self.get_object() # 根据传入的pk,获取一条数据 ser = self.get_serializer(instance=obj) return Response(ser.data) def put(self, request, pk): obj = self.get_object() ser = self.get_serializer(instance=obj, data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': "修改成功"}, status=201) else: return Response({'code': 101, 'msg': ser.errors}) def delete(self, request, pk): self.get_queryset().filter(pk=pk).delete() return Response('')
5个视图扩展类
五个视图扩展类必须配合GenericAPIView使用,不能与APIView配合使用
-
五个视图扩展类导入的模块
视图拓展类导入的模块 作用 CreateModelMixin 写了一个Create方法,就是原来咱们post中的代码 RetrieveModelMixin 写了一个retrieve方法,就是咱们原来的get中的代码 UpdateModelMixin 写了一个update方法,就是咱们原来的put中的代码 DestroyModelMixin 写了一个destroy方法,就是原来咱们的delete中的代码 ListModelMixin 写了一个list方法,就是原来咱们的get中的代码
-
视图py文件
class UserView(GenericAPIView, ListModelMixin, CreateModelMixin): # 配置两个 类属性 queryset = User.objects.all() serializer_class = UserSerializer def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) class UserDetailView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin): queryset = User.objects.all() serializer_class = UserSerializer def get(self,request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) def put(self, request, *args,**kwargs): return self.update(request,*args,**kwargs) def delete(self, request, *args,**kwargs): return self.destroy(request,*args,**kwargs)
9个视图子类
视图子类就是相当于视图类继承GenericAPIView+某个或某几个视图扩展类
使用rest_framework.generics可调用九个视图子类
-
一共有九个视图子类
视图子类 继承类 作用 CreateAPIView CreateModelMixin,
GenericAPIView有post方法,新增数据 DestroyAPIView DestroyModelMixin,
GenericAPIView有delete方法,删除数据 ListAPIView ListModelMixin,
GenericAPIView有get方法获取所有 UpdateAPIView UpdateModelMixin,
GenericAPIView有put和patch方法,修改数据 RetrieveAPIView RetrieveModelMixin,
GenericAPIView有get方法,获取一条 ListCreateAPIView ListModelMixin,
CreateModelMixin,
GenericAPIView有get获取所有,post方法新增 RetrieveDestroyAPIView RetrieveModelMixin,
DestroyModelMixin,
GenericAPIView有get方法获取一条,delete方法删除 RetrieveUpdateAPIView RetrieveModelMixin,
UpdateModelMixin,
GenericAPIView有get获取一条,put,patch修改 RetrieveUpdateDestroyAPIView RetrieveModelMixin,
UpdateModelMixin,
DestroyModelMixin,
GenericAPIView有get获取一条,put,patch修改,delete删除 -
视图类
from rest_framework.generics import ListAPIView,CreateAPIView, RetrieveAPIView,DestroyAPIView,UpdateAPIView from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView,RetrieveUpdateAPIView,RetrieveDestroyAPIView # 正常来讲 Destroy+Update 应该有一个 ,作者没加 class UserView(ListCreateAPIView): # 配置两个 类属性 queryset = User.objects.all() serializer_class = UserSerializer class UserDetailView(RetrieveUpdateDestroyAPIView): queryset = User.objects.all() serializer_class = UserSerializer
视图集
常用的视图集父类
-
ViewSet
继承自
APIView
与ViewSetMixin
,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等ViewSet主要通过继承ViewSetMixin来实现在调用as_view()时传入字典(如{‘get’:’list’})的映射处理工作。
-
GenericViewSet
使用ViewSet通常并不方便,因为list、retrieve、create、update、destory等方法都需要自己编写
可以通过继承Mixin扩展类来复用这些方法而无需自己编写,前提是需要继承GenericAPIView
GenericViewSet就帮助我们完成了这样的继承工作,继承自
GenericAPIView
与ViewSetMixin
,在实现了调用as_view()时传入字典(如{'get':'list'}
)的映射处理工作的同时,还提供了GenericAPIView
提供的基础方法,可以直接搭配Mixin扩展类使用 -
ModelViewSet
继承自
GenericViewSet
,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。 -
ReadOnlyModelViewSet
继承自
GenericViewSet
,同时包括了ListModelMixin、RetrieveModelMixin。
继承ModelViewSet编写五个接口
## 视图类 from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet class UserView(ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer ## 路由 path('user/', views.UserView.as_view({'get': 'list', 'post': 'create'})), path('user/<int:pk>', views.UserView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
源码分析ViewSetMixin
@classonlymethod def as_view(cls, actions=None, **initkwargs): # 路由中as_view中必须传参数,必须传字典:{'get': 'list', 'post': 'create'} if not actions: raise TypeError("The `actions` argument must be provided when " "calling `.as_view()` on a ViewSet. For example " "`.as_view({'get': 'list'})`") # 路由匹配成功,执行view(request),request是老的request def view(request, *args, **kwargs): # actions={'get': 'list', 'post': 'create'} for method, action in actions.items(): # method:get action:list # self 是视图类的对象中通过反射,查找list, # handler视图类中的list方法 handler = getattr(self, action) # 向视图类的对象中,反射 method:get,handler:list方法 # self.get=list setattr(self, method, handler) return self.dispatch(request, *args, **kwargs) return csrf_exempt(view) # 只要继承了ViewSetMixin,以后路由写法变了,都要写成:views.UserView.as_view({'get': 'list', 'post': 'create'}))这种格式 # 这样写好以后,对应的请求方式来了,就会执行配置的方法
以后只要继承了ViewSetMixin,视图类中可以写任意名字的方法,不用非得写get,post,delete
-
视图类
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet class StudentModelViewSet(ModelViewSet): queryset = Student.objects.all() serializer_class = StudentModelSerializer def login(self,request): return Response({"message":"登录成功"})
-
路由
urlpatterns = [ path("stu/login/",views.StudentModelViewSet.as_view({"get":"login"})) ]
drf视图组件思维导图
drf 视图组件
- 视图基类
- 基于APIView写五个接口
- 基于GenericAPIView写5个接口
- 5个视图扩展类
- 9个视图子类
- 视图集
两个视图基类
-
视图的两个基类分别是
APIView : 继承django的View
GenericAPIView: 继承APIView
-
GenericAPIView:属性和方法
-
属性
1.重点掌握 ① queryset # 要序列化的数据 ② serializer_class # 序列化类 2.了解 lookup_field # 通过get_object 获取单个对象的查询key值,value值是路由中传进来的 filter_backends # 过滤类 pagination_class # 分页类
-
方法
1.重点掌握 get_queryset # 获取要序列化的数据 get_object # 根据lookup_field配置的参数获取单个对象 get_serializer # 获取序列化类,咱们直接用的 get_serializer_class # 获取序列化类,不是咱们直接用的get_serializer调用了它 2.了解 filter_queryset # 跟过滤有关系 paginate_xxx # 跟分页有关
-
基于APIView写5个接口
class UserView(APIView): def get(self, request): res_list = User.objects.all() ser = UserSerializer(instance=res_list, many=True) return Response(ser.data) def post(self, request): ser = UserSerializer(data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': "新增成功"}, status=201) else: return Response({'code': 101, 'msg': ser.errors}) class UserDetailView(APIView): def get(self, request, pk): obj = User.objects.filter(pk=pk).first() ser = UserSerializer(instance=obj) return Response(ser.data) def put(self, request, pk): obj = User.objects.filter(pk=pk).first() ser = UserSerializer(instance=obj, data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': "修改成功"}, status=201) else: return Response({'code': 101, 'msg': ser.errors}) def delete(self, request, pk): User.objects.filter(pk=pk).delete() return Response('')
基于GenericAPIView写5个接口
class UserView(GenericAPIView): # 配置两个 类属性 queryset = User.objects.all() serializer_class = UserSerializer # def get_queryset(self): # if self.request.method=='GET': # return User.objects.all() # else: # return Publish.object.all() def get(self, request): res_list = self.get_queryset() # 提高扩展性 ser = self.get_serializer(instance=res_list, many=True) 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': "新增成功"}, status=201) else: return Response({'code': 101, 'msg': ser.errors}) class UserDetailView(GenericAPIView): queryset = User.objects.all() serializer_class = UserSerializer def get(self, request, pk): # obj = self.get_queryset().filter(pk=pk).first() # queryset.get({'pk':'有名分组分出来的'} obj = self.get_object() # 根据传入的pk,获取一条数据 ser = self.get_serializer(instance=obj) return Response(ser.data) def put(self, request, pk): obj = self.get_object() ser = self.get_serializer(instance=obj, data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': "修改成功"}, status=201) else: return Response({'code': 101, 'msg': ser.errors}) def delete(self, request, pk): self.get_queryset().filter(pk=pk).delete() return Response('')
5个视图扩展类
五个视图扩展类必须配合GenericAPIView使用,不能与APIView配合使用
-
五个视图扩展类导入的模块
视图拓展类导入的模块 作用 CreateModelMixin 写了一个Create方法,就是原来咱们post中的代码 RetrieveModelMixin 写了一个retrieve方法,就是咱们原来的get中的代码 UpdateModelMixin 写了一个update方法,就是咱们原来的put中的代码 DestroyModelMixin 写了一个destroy方法,就是原来咱们的delete中的代码 ListModelMixin 写了一个list方法,就是原来咱们的get中的代码
-
视图py文件
class UserView(GenericAPIView, ListModelMixin, CreateModelMixin): # 配置两个 类属性 queryset = User.objects.all() serializer_class = UserSerializer def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) class UserDetailView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin): queryset = User.objects.all() serializer_class = UserSerializer def get(self,request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) def put(self, request, *args,**kwargs): return self.update(request,*args,**kwargs) def delete(self, request, *args,**kwargs): return self.destroy(request,*args,**kwargs)
9个视图子类
视图子类就是相当于视图类继承GenericAPIView+某个或某几个视图扩展类
使用rest_framework.generics可调用九个视图子类
-
一共有九个视图子类
视图子类 继承类 作用 CreateAPIView CreateModelMixin,
GenericAPIView有post方法,新增数据 DestroyAPIView DestroyModelMixin,
GenericAPIView有delete方法,删除数据 ListAPIView ListModelMixin,
GenericAPIView有get方法获取所有 UpdateAPIView UpdateModelMixin,
GenericAPIView有put和patch方法,修改数据 RetrieveAPIView RetrieveModelMixin,
GenericAPIView有get方法,获取一条 ListCreateAPIView ListModelMixin,
CreateModelMixin,
GenericAPIView有get获取所有,post方法新增 RetrieveDestroyAPIView RetrieveModelMixin,
DestroyModelMixin,
GenericAPIView有get方法获取一条,delete方法删除 RetrieveUpdateAPIView RetrieveModelMixin,
UpdateModelMixin,
GenericAPIView有get获取一条,put,patch修改 RetrieveUpdateDestroyAPIView RetrieveModelMixin,
UpdateModelMixin,
DestroyModelMixin,
GenericAPIView有get获取一条,put,patch修改,delete删除 -
视图类
from rest_framework.generics import ListAPIView,CreateAPIView, RetrieveAPIView,DestroyAPIView,UpdateAPIView from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView,RetrieveUpdateAPIView,RetrieveDestroyAPIView # 正常来讲 Destroy+Update 应该有一个 ,作者没加 class UserView(ListCreateAPIView): # 配置两个 类属性 queryset = User.objects.all() serializer_class = UserSerializer class UserDetailView(RetrieveUpdateDestroyAPIView): queryset = User.objects.all() serializer_class = UserSerializer
视图集
常用的视图集父类
-
ViewSet
继承自
APIView
与ViewSetMixin
,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等ViewSet主要通过继承ViewSetMixin来实现在调用as_view()时传入字典(如{‘get’:’list’})的映射处理工作。
-
GenericViewSet
使用ViewSet通常并不方便,因为list、retrieve、create、update、destory等方法都需要自己编写
可以通过继承Mixin扩展类来复用这些方法而无需自己编写,前提是需要继承GenericAPIView
GenericViewSet就帮助我们完成了这样的继承工作,继承自
GenericAPIView
与ViewSetMixin
,在实现了调用as_view()时传入字典(如{'get':'list'}
)的映射处理工作的同时,还提供了GenericAPIView
提供的基础方法,可以直接搭配Mixin扩展类使用 -
ModelViewSet
继承自
GenericViewSet
,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。 -
ReadOnlyModelViewSet
继承自
GenericViewSet
,同时包括了ListModelMixin、RetrieveModelMixin。
继承ModelViewSet编写五个接口
## 视图类 from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet class UserView(ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer ## 路由 path('user/', views.UserView.as_view({'get': 'list', 'post': 'create'})), path('user/<int:pk>', views.UserView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
源码分析ViewSetMixin
@classonlymethod def as_view(cls, actions=None, **initkwargs): # 路由中as_view中必须传参数,必须传字典:{'get': 'list', 'post': 'create'} if not actions: raise TypeError("The `actions` argument must be provided when " "calling `.as_view()` on a ViewSet. For example " "`.as_view({'get': 'list'})`") # 路由匹配成功,执行view(request),request是老的request def view(request, *args, **kwargs): # actions={'get': 'list', 'post': 'create'} for method, action in actions.items(): # method:get action:list # self 是视图类的对象中通过反射,查找list, # handler视图类中的list方法 handler = getattr(self, action) # 向视图类的对象中,反射 method:get,handler:list方法 # self.get=list setattr(self, method, handler) return self.dispatch(request, *args, **kwargs) return csrf_exempt(view) # 只要继承了ViewSetMixin,以后路由写法变了,都要写成:views.UserView.as_view({'get': 'list', 'post': 'create'}))这种格式 # 这样写好以后,对应的请求方式来了,就会执行配置的方法
以后只要继承了ViewSetMixin,视图类中可以写任意名字的方法,不用非得写get,post,delete
-
视图类
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet class StudentModelViewSet(ModelViewSet): queryset = Student.objects.all() serializer_class = StudentModelSerializer def login(self,request): return Response({"message":"登录成功"})
-
路由
urlpatterns = [ path("stu/login/",views.StudentModelViewSet.as_view({"get":"login"})) ]