一、
# Django REST framwork 提供的视图的主要作用: 控制序列化器的执行(检验、保存、转换数据) 控制数据库查询的执行 # APIView:继承了原生Django的View # GenericAPIView:继承了APIView -queryset = models.Book.objects.all() -serializer_class = serializer.BookModelSerializer -get_queryset:获取配置的queryset -get_object:路由中的分组字段必须是pk -get_serializer:获取配置的序列化类 # 最终总结 #两个基类 APIView:如果跟models没有关系(没有数据库相关操作),就继承它 GenericAPIView:有关数据库操作,queryset 和serializer_class
2.代码
models.py
from django.db import models class Book(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length=32,null=True) price = models.DecimalField(max_digits=5, decimal_places=2,null=True) publish = models.CharField(max_length=32,null=True)
serializer.py
from app01 import models from rest_framework import serializers class BookModelSerializer(serializers.ModelSerializer): class Meta: model = models.Book fields = '__all__'
urls.py
from django.urls import path,re_path from app01 import views urlpatterns = [ #继承APIView # path('books/',views.BookAPIView.as_view()), # re_path('^books/(?P<pk>d+)', views.BookDetailAPIView.as_view()), #继承GenericAPIView path('books/',views.BookGenericView.as_view()), re_path('^books/(?P<pk>d+)', views.BookDetailGenericAPIView.as_view()), ]
views.py----->继承了APIView
# 继承了APIView class BookAPIView(APIView): def get(self, request): book_list = models.Book.objects.all() ser = serializer.BookModelSerializer(book_list, many=True) return Response(ser.data) def post(self, request): ser = serializer.BookModelSerializer(data=request.data) if ser.is_valid(): ser.save() return Response('成功') class BookDetailAPIView(APIView): def get(self, request, pk): book = models.Book.objects.get(id=pk) ser = serializer.BookModelSerializer(book) return Response(ser.data) def put(self, request, pk): book = models.Book.objects.get(id=pk) ser = serializer.BookModelSerializer(book, data=request.data) if ser.is_valid(): ser.save() return Response('修改成功') def delete(self, request, pk): models.Book.objects.filter(id=pk).delete() return Response('删除成功')
views.py----->继承了GenericAPIView
#继承了GenericAPIView class BookGenericView(GenericAPIView): queryset = models.Book.objects.all() serializer_class = serializer.BookModelSerializer def get(self, request, *args, **kwargs): obj = self.get_queryset() ser = self.get_serializer(obj, many=True) return Response(ser.data) def post(self, request, *args, **kwargs): ser=self.get_serializer(data=request.data) if ser.is_valid(): ser.save() return Response('成功') class BookDetailGenericAPIView(GenericAPIView): queryset = models.Book.objects.all() serializer_class = serializer.BookModelSerializer def get(self, request, *args, **kwargs): obj = self.get_object() ser = self.get_serializer(obj) return Response(ser.data) def put(self, request, *args, **kwargs): obj = self.get_object() ser = self.get_serializer(obj, data=request.data) if ser.is_valid(): ser.save() return Response('修改成功') def delete(self, request, *args, **kwargs): self.queryset.filter(id=kwargs.get('pk')).delete() return Response('删除成功')
二、自定义两个扩展类
需要修改views.py ------演变过程
#自定义了两个扩展类 class ListView(): def list(self,request, *args, **kwargs): obj = self.get_queryset() ser = self.get_serializer(obj, many=True) return Response(ser.data) class CreateView(): def create(self,request, *args, **kwargs): ser=self.get_serializer(data=request.data) if ser.is_valid(): ser.save() return Response('成功') class BookGenericView(GenericAPIView,CreateView,ListView): queryset = models.Book.objects.all() serializer_class = serializer.BookModelSerializer 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 BookDetailGenericAPIView(GenericAPIView): queryset = models.Book.objects.all() serializer_class = serializer.BookModelSerializer def get(self, request, *args, **kwargs): obj = self.get_object() ser = self.get_serializer(obj) return Response(ser.data) def put(self, request, *args, **kwargs): obj = self.get_object() ser = self.get_serializer(obj, data=request.data) if ser.is_valid(): ser.save() return Response('修改成功') def delete(self, request, *args, **kwargs): self.queryset.filter(id=kwargs.get('pk')).delete() return Response('删除成功')
三、
1.知识储备
#5个视图扩展类(rest_framework.mixins) CreateModelMixin:create方法创建一条 DestroyModelMixin:destory方法删除一条 ListModelMixin:list方法获取所有 RetrieveModelMixin:retrieve获取一条 UpdateModelMixin:update修改一条
2.代码
需要修改views.py ------演变过程
### 使用drf提供的视图扩展类 ##5个视图扩展类 from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModelMixin, RetrieveModelMixin, UpdateModelMixin class BookGenericView(GenericAPIView,ListModelMixin,CreateModelMixin): queryset = models.Book.objects.all() serializer_class = serializer.BookModelSerializer 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 BookDetailGenericAPIView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin): queryset = models.Book.objects.all() serializer_class = serializer.BookModelSerializer 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个子类视图
1.知识储备
#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删除
2.代码
from rest_framework.mixins import ListModelMixin, CreateModelMixin #### 9个视图子类 class CreateListGenericAPIView(GenericAPIView,CreateModelMixin,ListModelMixin): def get(self,request,*args,**kwargs): return self.list(request,*args,**kwargs) def post(self,request,*args,**kwargs): return self.create(request,*args,**kwargs)
from rest_framework.generics import CreateAPIView,ListAPIView,ListCreateAPIView from rest_framework.generics import UpdateAPIView,RetrieveAPIView,DestroyAPIView,RetrieveUpdateAPIView,RetrieveDestroyAPIView,
RetrieveUpdateDestroyAPIView # class BookGenericView(CreateAPIView): # class BookGenericView(ListAPIView): class BookGenericView(ListCreateAPIView): queryset = models.Book.objects.all() serializer_class = serializer.BookModelSerializer # class BookDetailGenericAPIView(RetrieveAPIView): # class BookDetailGenericAPIView(RetrieveAPIView,UpdateAPIView): class BookDetailGenericAPIView(RetrieveUpdateDestroyAPIView): queryset = models.Book.objects.all() serializer_class = serializer.BookModelSerializer
五、视图集
1.储备知识
#视图集 # 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
2.代码
urls.py
urlpatterns = [ # ## 使用视图集 # path('books_set/', views.BookSetView.as_view({'get':'list','post':'create'})), # # path('books_set/', views.BookSetView.as_view()), # 直接报错 # re_path('^books_set/(?P<pk>d+)', views.BookSetView.as_view({'get':'retrieve','put':'update','delete':'destroy'})), # path('books_mix/', views.BookView.as_view({'get':'lili'})), path('books_mix2/', views.BookView.as_view({'get':'xxx'})), ]
views.py
# 视图集 # 继承一个东西,有5个接口 from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ReadOnlyModelViewSet # 只有查询 from rest_framework.views import APIView class BookSetView(ModelViewSet): queryset = models.Book.objects.all() serializer_class = serializer.BookModelSerializer # ViewSetMixin:视图类中的方法名,可以随便写,只需要映射对就可以 from rest_framework.viewsets import ViewSetMixin,ViewSet # class BookView(ViewSetMixin,APIView): class BookView(ViewSet): def lili(self,request,*args,**kwargs): print(self.action) return Response('lili') def xxx(self,request,*args,**kwargs): return Response('xxxx')
六、action的使用
# 只要继承了ViewSetMixin类 # 路由配置:path('books_mix/', views.BookView.as_view({'get':'lili'})) # 视图类的方法中就会有个action class BookView(ViewSet): def lili(self,request,*args,**kwargs): print(self.action) return Response('lili') # ViewSetMixin以后只要继承它,路由的配置就发生变化了,只需要写映射即可
七、路由的使用
# 自动生成路由 # SimpleRouter # DefaultRouter # 继承了ViewSetMixin的视图类,以后写路由,可以自动生成 from rest_framework import routers # 实例化得到一个对象 router = routers.SimpleRouter() # 注册进路由 router.register('books', views.BookSetView) # 把自动生成的路由配置到urlpatterns中 -urlpatterns += router.urls -re_path(r'v1/', include(router.urls)) # 配置路由的方式 -最原始的 -path('books/', views.BookAPIView.as_view()), -ViewSetMixin的视图类 -path('books_set/', views.BookSetView.as_view({'get':'list','post':'create'})) -ViewSetMixin的视图类 -自动生成,上面讲的 # action -当自动生成路由的时候,由于视图类中还有其它方法,是无法自动生成路由的 -加action装饰器: -methods:什么请求方式会触发被装饰函数的执行 -detail:是True是基于带id的路由生成的,如果是False,是基于不带id的路由生成的 -@action(methods=['get'], detail=True)