06 视图函数封装(二)
重写View视图函数,将多个类进行合并
from rest_framework import views # APIView from rest_framework import generics # 公共的通用的视图类 from rest_framework import mixins # 混合继承类 from rest_framework import viewsets # ModelViewSet
1、路由分发
from django.urls import path from DRFServer.views import BookView,BookEditView,BookModelViewSet urlpatterns=[ # path('list/',BookView.as_view()), #Django 2.0版本前写法 # path('retrieve/(?P<id>\d+)',BookEditView.as_view()), # Django 2.0后的写法 # path('retrieve/<int:id>',BookEditView.as_view()), path('list/',BookModelViewSet.as_view({"get":"list","post":"create"})), path("retrieve/<int:id>",BookModelViewSet.as_view({"get":"retrieve","put":"update","delete":"destroy"})) ]
给as_view()传入字典,让对应请求使用自定义方法,前提是View必须继承ViewSetMixin类
2、View类修改继承
from django.shortcuts import render from django.http import HttpResponse, JsonResponse from django.core import serializers from DRFServer.models import Book, Publisher import json # Create your views here. from django.views import View from rest_framework.views import APIView from rest_framework.response import Response from DRFServer.serializers import BookSerializer # class BookView(View): # 版本一,使用values和JsonResponse实现序列号 # def get(self,request): # book_list=Book.objects.values("id","title","pub_time","publisher","author") # # queryset无法直接被json系列化,先对其list # book_list=list(book_list) # ret=[] # for book in book_list: # publisher_id=book["publisher"] # publisher_obj=Publisher.objects.filter(id=publisher_id).first() # book["publisher"]={"id":publisher_id,"title":publisher_obj.title} # ret.append(book) # # ensure_ascii=False避免中文乱码 # # ret=json.dumps(book_list,ensure_ascii=False) # # return HttpResponse(ret) # return JsonResponse(ret,safe=False,json_dumps_params={"ensure_ascii":False}) # 版本二,使用django serializers实现序列号 # def get(self,request): # book_list=Book.objects.all() # ret=serializers.serialize("json",book_list,ensure_ascii=False) # return HttpResponse(ret) class GenericAPIView(APIView): #这里其实在具体View中去重新赋值,self去查找就不会查找到None query_set = None serializer_class = None def get_queryset(self): return self.query_set def get_obj(self, id): return self.get_queryset().filter(pk=id).first() def get_serializer(self, *args, **kwargs): return self.serializer_class(*args, **kwargs) # 定义混合类 class ListModelMixin(object): def list(self, request): book_list = self.get_queryset() ret = self.get_serializer(book_list, many=True) return Response(ret.data) class CreateModelMixin(object): def create(self, request): serializer = self.get_serializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) else: return Response(serializer.errors) class RetrieveModelMixin(object): def retrieve(self, request, id): obj = self.get_obj(id) ret = self.get_serializer(obj) return Response(ret.data) class UpdateModelMixin(object): def update(self, request, id): obj = self.get_obj(id) serializers = self.get_serializer(instance=obj, data=request.data, partial=True) if serializers.is_valid(): serializers.save() return Response(serializers.data) return Response(serializers.errors) class DestroyModelMixin(object): def destroy(self, request, id): obj = self.get_obj(id) obj.delete() return Response("") class ListCreateModel(GenericAPIView,ListModelMixin,CreateModelMixin): pass class BookView(ListCreateModel): query_set = Book.objects.all() serializer_class = BookSerializer def get(self, request): # book_obj=Book.objects.first() # 一条数据 # ret=BookSerializer(book_obj) # book_list=Book.objects.all() # 多条数据 # ret=BookSerializer(book_list,many=True) # book_list=self.get_queryset() # ret=BookSerializer(book_list,many=True) # return Response(ret.data) return self.list(request) def post(self, request): # serializer=BookSerializer(data=request.data) # if serializer.is_valid(): # serializer.save() # return Response(serializer.data) # else: # return Response(serializer.errors) return self.create(request) class RetrieveUpdateDestroyModel(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin): pass class BookEditView(RetrieveUpdateDestroyModel): serializer_class = BookSerializer query_set = Book.objects.all() def get(self, request, id): # book_obj=Book.objects.filter(id=id).first() # ret=BookSerializer(book_obj) # return Response(ret.data) return self.retrieve(request, id) def put(self, request, id): return self.update(request, id) # data=request.data # book_obj = Book.objects.filter(id=id).first() # partial=True允许部分更新 # serializers=BookSerializer(instance=book_obj,data=data,partial=True) # if serializers.is_valid(): # 方式一 # serializers.update(book_obj,serializers.validated_data) # 方式二 # serializers.save() # return Response(serializers.data) # else: # return Response(serializers.errors) def delete(self, request, id): # book_obj=Book.objects.filter(id=id).first() # book_obj.delete() # return Response("") return self.destroy(request, id) from rest_framework.viewsets import ViewSetMixin class BookModelViewSet(ViewSetMixin,GenericAPIView,ListModelMixin,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin): serializer_class = BookSerializer query_set = Book.objects.all() #路由中对应的方法,在继承中找即可
使用View类继承ViewSetMixin类,该类重写了as_view()方法
3、使用框架提供的ModelViewSet
URL修改
4、DRF路由
使用drf提供的DefaultRouter生成urls,这样会暴露出全部api,一般采用自己配置