restframework 视图
重要知识点
as_view()获取的是view方法名,当url配版成功,执行view方法
一、逻辑封装(mixins, generics)
path('author/', views.AuthorView.as_view()), path('author/<pk>/', views.AuthorDetailView.as_view()),
from rest_framework import mixins, generics """ 本质:封装逻辑 1.return 父类的方法 2.queryset serializer_class 两个参数必要(看源码) 3.mixins.ListModelMixin和mixins.CreateModelMixin 没有的方法到generics.GenericAPIView去找 4.url的参数要改成pk,根据get_obj() 源码 """ class AuthorView(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = Author.objects.all() # print(queryset) serializer_class = AuthorModelSerializer 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 AuthorDetailView(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView): queryset = Author.objects.all() serializer_class = AuthorModelSerializer 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)
二、封装类(generics)
path('author/', views.AuthorView.as_view()), path('author/<pk>/', views.AuthorDetailView.as_view()),
from rest_framework import generics """ 本质:对类进行封装(具体情况看源码) 1.只需要 queryset 和 serializer_class 2.generics.ListCreateAPIView -----> mixins.ListModelMixin, mixins.CreateModelMixin, GenericAPIView 和get post方法 3.generics.RetrieveUpdateDestroyAPIView -----> mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin, GenericAPIView 和 get put patch 和delete """ class AuthorView(generics.ListCreateAPIView): queryset = Author.objects.all() serializer_class = AuthorModelSerializer class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView): queryset = Author.objects.all() serializer_class = AuthorModelSerializer
三、一个视图CBV
有两个视图的原因:有两个get方法
path('author/', views.AuthorViewSet.as_view({'get': 'list', 'post': 'create'})), path('author/<pk>/', views.AuthorViewSet.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
from rest_framework import viewsets """ 重点:有两个视图CBV的原因,有两个get方法 源码分析 1.查找as_view(),并传递参数 {'get': 'list', 'post': 'create'} AuthorViewSet-->ModelViewSet-->GenericViewSet-->ViewSetMixin(找到as_view(传递参数action),返回值view, 找返回值)-->view()(找到view) for method, action in actions.items(): actions: {'get': 'list', 'post': 'create'} handler = getattr(self, action) handler=self.list handler=self.create setattr(self, method, handler) self.get=handler=self.list ->self.get=self.list 返回 dispatch() 2.查找 dispatch() AuthorViewSet-->ModelViewSet-->GenericViewSet-->generics.GenericAPIView-->views.APIView 找到dispatch(self, request, *args, **kwargs) if request.method.lower() in self.http_method_names: get 在 方法里 handler = getattr(self, request.method.lower(), get既是list self.http_method_not_allowed) else: handler = self.http_method_not_allowed get找到list解决了 有两个list的问题 """ class AuthorViewSet(viewsets.ModelViewSet): queryset = Author.objects.all() serializer_class = AuthorModelSerializer