DRF-视图类组件
补充
GET
books-------->查看数据--------------------> 返回所有数据列表 :[{},{},{}]
POST
books-------->添加数据--------------------->返回添加数据 :{}
PUT
books/1------->更新pk=1的数据--------------->返回更新后的数据: {}
Delete
books/1-------> 删除pk=1的数据-------------->返回空
GET
books/1------->查看单条数据 --------------->返回查看的单条数据 {}
普通版
缺点:缺点再实际工作中我们可能建多个表,导致代码过于冗余,所以我们要进行进一步封装。
from django.shortcuts import render,HttpResponse from django.views import View # Create your views here. # 导入djangorestframework # 当前访问视图类下设置解析方式 from rest_framework.parsers import JSONParser from rest_framework.views import APIView from app01.models import * from rest_framework import serializers from rest_framework.response import Response class BookSerializer(serializers.ModelSerializer): class Meta: model=Book # fields=["title","price"] fields="__all__" def get_authors(self,obj): ret=[] for i in obj.authors.all(): ret.append(i.name) return ret class LoginView(APIView): parser_classes = [JSONParser] def get(self,request): book_list = Book.objects.all() serializer = BookSerializer(book_list,many=True) return Response(serializer.data) def post(self,request): print('body',request.body) print(request.data) print('data',request.data) return HttpResponse('OK') class SLoginView(APIView): def get(self,request,id): my_obj = Book.objects.get(pk=id) serializer = BookSerializer(my_obj, many=False) return Response(serializer.data) pass def put(self,request,id): my_obj = Book.objects.get(pk=id) serializer = BookSerializer(data=request.data,instance=my_obj) if serializer.is_valid(): serializer.save() return Response(serializer.data) else: return Response(serializer.errors) def delete(self,request,id): my_obj = Book.objects.get(pk=id).delete() return Response("")
第一步封装---对里面的数据操作进行封装
url中
url(r'^authors/$', views.AuthorsView.as_view()), url(r'^authors/(?P<pk>\d+)/', views.SAuthorsView.as_view()),
视图函数中
from rest_framework import generics from rest_framework.mixins import ListModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin from rest_framework import generics class PublishView(ListModelMixin,CreateModelMixin,generics.GenericAPIView): queryset = Publish.objects.all() serializer_class = PublishSerializer 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 SPublishView(UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin,generics.GenericAPIView): queryset = Publish.objects.all() serializer_class = PublishSerializer 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)
第二步封装,对两个类中的方法进行封装,然后把两个视图合为一个视图再进行封装
url中
url(r'^authors/$', views.AuthorsView.as_view({"get":"list","post":"create"})), url(r'^authors/(?P<pk>\d+)/', views.AuthorsView.as_view({"get":"retrieve","delete":"destroy","put":"update"})),
视图中
from rest_framework.viewsets import ModelViewSet class AuthorsView(ModelViewSet): queryset = Author.objects.all() serializer_class = AuthorSerializer
对封装后的视图类组件的源码解析
1 启动Django,执行AuthorsView.as_view 找继承最近的as_view url(r'^authors/$', views.AuthorsView.as_view({"get":"list","post":"create"})), url(r'^authors/(?P<pk>\d+)/', views.AuthorsView.as_view({"get":"retrieve","delete":"destroy","put":"update"})), 2 在AuthorsView,下找as_view方法 class AuthorsView(ModelViewSet): queryset = Author.objects.all() erializer_class = AuthorSerializer 没找到,去父类ModelViewSet下找 3 在ModelViewSet,下找as_view方法 class ModelViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, GenericViewSet):pass 没找到,去父类GenericViewSet下找 4 在GenericViewSet,下找as_view方法 class GenericViewSet(ViewSetMixin, generics.GenericAPIView):pass 没找到,去父类ViewSetMixin下找 //******找到我们要的as_view方法 5 在ViewSetMixin,下找as_view方法,我们找到了as_view() class ViewSetMixin(object): @classonlymethod # *****这里我们把url中的as_view参数{"get":"retrieve","delete":"destroy","put":"update"}传给了actions,开始关注actions def as_view(cls, actions=None, **initkwargs): def view(request, *args, **kwargs): for method, action in actions.items(): handler = getattr(self, action) setattr(self, method, handler) return self.dispatch(request, *args, **kwargs) return csrf_exempt(view) 我们找到了as_view() 然后返回view // ******这里开始浏览器请求数据 当浏览器访问时我们执行view() handler = getattr(self, action) 我们得到self.retrieve 这个方法 setattr(self, method, handler) 我们self.get = self.retrieve 我们把方法赋给相应的请求 return self.dispatch(request, *args, **kwargs) 这里我们又回到APIview下的内容分发了 6 在APIview中的dispatch中 def dispatch(self, request, *args, **kwargs): # *****进行内容分发,self.get,self.put...由于在步骤5我们又对他们进行了赋值,相当于self.retrieve,self.update... handler = getattr(self, request.method.lower(),self.http_method_not_allowed) # 这里执行函数retrieve()....... response = handler(request, *args, **kwargs) return self.response