13 视图组件
1 ,视图
两个视图基类
APIView
GenericAPIView
1.1 ,基于APIView写的5个接口
#### views.py from rest_framework.generics import GenericAPIView from app01.models import Book from app01.ser import BookSerializer # 基于APIView写的 class BookView(APIView): def get(self,request): book_list=Book.objects.all() book_ser=BookSerializer(book_list,many=True) return Response(book_ser.data) def post(self,request): book_ser = BookSerializer(data=request.data) if book_ser.is_valid(): book_ser.save() return Response(book_ser.data) else: return Response({'status':101,'msg':'校验失败'}) class BookDetailView(APIView): def get(self, request,pk): book = Book.objects.all().filter(pk=pk).first() book_ser = BookSerializer(book) return Response(book_ser.data) def put(self, request,pk): book = Book.objects.all().filter(pk=pk).first() book_ser = BookSerializer(instance=book,data=request.data) if book_ser.is_valid(): book_ser.save() return Response(book_ser.data) else: return Response({'status': 101, 'msg': '校验失败'}) def delete(self,request,pk): ret=Book.objects.filter(pk=pk).delete() return Response({'status': 100, 'msg': '删除成功'}) #models.py class Book(models.Model): name=models.CharField(max_length=32) price=models.DecimalField(max_digits=5,decimal_places=2) publish=models.CharField(max_length=32) #ser.py class BookSerializer(serializers.ModelSerializer): class Meta: model=Book fields='__all__' # urls.py path('books/', views.BookView.as_view()), re_path('books/(?P<pk>\d+)', views.BookDetailView.as_view()),1.2, 基于GenericAPIView写的5个接口
### views.py from rest_framework.views import APIView from rest_framework.response import Response from .models import Publish from .seriazlizer import PublishSerializer ### 通过继承GenericAPIView写 5个接口 from rest_framework.views import APIView from rest_framework.generics import GenericAPIView # 继承APIView,写了几个类属性 """ # 类属性 queryset = None # 所有数据 serializer_class = None # 序列化的类 lookup_field = 'pk' # 查询单条转换器的字段 # 三个方法 self.get_queryset() # 获取所有的数据 self.get_serializer # 获取序列化类 self.get_object() # 获取单条数据 """ class PublishView(GenericAPIView): queryset = Publish.objects.all() serializer_class = PublishSerializer def get(self, request): obj = self.get_queryset() ser = self.get_serializer(instance=obj, many=True) return Response(data=ser.data) def post(self, request): ser = self.get_serializer(data=request.data) if ser.is_valid(): ser.save() return Response(ser.data) else: return Response(ser.errors) # ser.is_valid(raise_exception=True) class PublishDetailView(GenericAPIView): queryset = Publish.objects.all() serializer_class = PublishSerializer def get(self, request, pk): obj = self.get_object() # 获取单条 ,根据pk ser = PublishSerializer(instance=obj) return Response(data=ser.data) def put(self, request, pk): obj = self.get_object() # 数据不存在 ,None,如果instance是None,ser.save -->是新增 ser = self.get_serializer(data=request.data, instance=obj) if ser.is_valid(): ser.save() return Response(ser.data) else: return Response(ser.errors) # ser.is_valid(raise_exception=True) def delete(self, request, pk): res = self.get_object().delete() # 返回影响的行数 if res >= 1: return Response() else: return Response('要删除的数据不存在') ###urls.py from django.contrib import admin from django.urls import path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path('publish/',views.PublishView.as_view()), path('publish/<int:pk>',views.PublishDetailView.as_view()), ###models.py class Publish(models.Model): name = models.CharField(max_length=16) address = models.CharField(max_length=64) ####serializer.py class PublishSerializer(serializers.ModelSerializer): class Meta: model = Publish fields = "__all__"
1.3 基于GenericAPIView和5个视图扩展类写的接口
from rest_framework.mixins import ListModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin # views.py class Book3View(GenericAPIView,ListModelMixin,CreateModelMixin): queryset=Book.objects serializer_class = BookSerializer def get(self,request): return self.list(request) def post(self,request): return self.create(request) class Book3DetailView(GenericAPIView,RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin): queryset = Book.objects serializer_class = BookSerializer def get(self, request,pk): return self.retrieve(request,pk) def put(self, request,pk): return self.update(request,pk) def delete(self,request,pk): return self.destroy(request,pk) # urls.py # 使用GenericAPIView+5 个视图扩展类 重写的 path('books3/', views.Book3View.as_view()), re_path('books3/(?P<pk>\d+)', views.Book3DetailView.as_view()),9个视图子类
class ListAPIView(GenericAPIView,ListModelMixin): def get(self,request): return self.list(request) class CreateAPIView(GenericAPIView,CreateModelMixin): def post(self,request): return self.create(request) class ListCreateAPIView(GenericAPIView,ListModelMixin,CreateModelMixin): def get(self, request): return self.list(request) def post(self, request): return self.create(request) class DestroyAPIView(GenericAPIView,DestroyModelMixin): def delete(self, request, pk): return self.destroy(request, pk) class UpdateAPIView(GenericAPIView,UpdateModelMixin): def put(self, request, pk): return self.update(request, pk) class RetrieveAPIView(GenericAPIView,RetrieveModelMixin): def get(self, request, pk): return self.retrieve(request, pk)class RetrieveDestroyAPIView(GenericAPIView,RetrieveModelMixin,DestroyModelMixin):
def get(self, request, pk):
return self.retrieve(request, pk)
def delete(self, request, pk):
return self.destroy(request, pk)
class RetrieveUpdateAPIView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin):
def get(self, request, pk):
return self.retrieve(request, pk)
def put(self, request, pk):
return self.update(request, pk)
class RetrieveUpdateDestroyAPIView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
def get(self, request, pk):
return self.retrieve(request, pk)
def delete(self, request, pk):
return self.destroy(request, pk)
def put(self, request, pk):
return self.update(request, pk)1.4 使用ModelViewSet编写5个接口
# views.py from rest_framework.viewsets import ModelViewSet class Book5View(ModelViewSet): #5个接口都有,但是路由有点问题 queryset = Book.objects serializer_class = BookSerializer # urls.py # 使用ModelViewSet编写5个接口 path('books5/', views.Book5View.as_view(actions={'get':'list','post':'create'})), #当路径匹配,又是get请求,会执行Book5View的list方法 re_path('books5/(?P<pk>\d+)', views.Book5View.as_view(actions={'get':'retrieve','put':'update','delete':'destroy'})),1.5 源码分析ViewSetMixin
# 重写了as_view # 核心代码(所以路由中只要配置了对应关系,比如{'get':'list'}),当get请求来,就会执行list方法 for method, action in actions.items(): #method:get # action:list handler = getattr(self, action) #执行完上一句,handler就变成了list的内存地址 setattr(self, method, handler) #执行完上一句 对象.get=list #for循环执行完毕 对象.get:对着list 对象.post:对着create1.6 继承ViewSetMixin的视图类
# views.py from rest_framework.viewsets import ViewSetMixin class Book6View(ViewSetMixin,APIView): #一定要放在APIVIew前 def get_all_book(self,request): print("xxxx") book_list = Book.objects.all() book_ser = BookSerializer(book_list, many=True) return Response(book_ser.data) # urls.py #继承ViewSetMixin的视图类,路由可以改写成这样 path('books6/', views.Book6View.as_view(actions={'get': 'get_all_book'})),1.1视图继承关系
总结:
#两个基类 APIView GenericAPIView:有关数据库操作,queryset 和serializer_class #5个视图扩展类(rest_framework.mixins) CreateModelMixin:create方法创建一条 DestroyModelMixin:destory方法删除一条 ListModelMixin:list方法获取所有 RetrieveModelMixin:retrieve获取一条 UpdateModelMixin:update修改一条 #9个子类视图(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删除 #视图集 ViewSetMixin:重写了as_view ViewSet: 继承ViewSetMixin和APIView GenericViewSet:继承ViewSetMixin, generics.GenericAPIView ModelViewSet:继承mixins.CreateModelMixin,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin,mixins.ListModelMixin,GenericViewSet ReadOnlyModelViewSet:继承mixins.RetrieveModelMixin,mixins.ListModelMixin,GenericViewSet补充
1 在pycharm中查看类的继承关系