视图继承关系
两个视图基类
APIView
# from rest_framework.views import APIView
APIView是REST framework提供的所有视图的基类,继承自Django的view父类
APIView与View的不同之处:
- 传入到视图方法中的是REST framework的
Request对象,而不是Django的HttpRequeset对象; - 视图方法可以返回REST framework的
Response对象,视图会为响应数据设置(render)符合前端要求的格式; - 任何
APIException异常都会被捕获到,并且处理成合适的响应信息; - 在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。
APIView支持定义的类属性:
- authentication_classes 列表或元祖,身份认证类
- permissoin_classes 列表或元祖,权限检查类
- throttle_classes 列表或元祖,流量控制类
基于APIView写的五种接口
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)
from rest_framework import serializers from app01.models import Book class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = '__all__'
from django.contrib import admin from django.urls import path,re_path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), re_path(r'^books/(?P<pk>\d)', views.BookAPIView.as_view()), path('books/', views.BooksAPIView.as_view()) ]
from rest_framework.views import APIView from rest_framework.response import Response from app01.ser import BookSerializer from app01.models import Book class BookAPIView(APIView): def get(self,request,pk): book = Book.objects.filter(id=pk).first() book_ser = BookSerializer(instance=book) return Response(book_ser.data) def put(self,request,pk): book = Book.objects.filter(id=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,'message':'修改失败'}) def delete(self,request,pk): Book.objects.filter(id=pk).delete() return Response({'status':100,'message':'删除成功'}) class BooksAPIView(APIView): def get(self,request): books = Book.objects.all() books_ser = BookSerializer(instance=books,many=True) return Response(books_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,'message':'添加失败'})
GenericAPIView[通用视图类]
# from rest_framework.generics import GenericAPIView
继承自APIView,主要增加了操作序列化器和数据库查询的方法,作用是为Mixin扩展类的执行提供方法支持。通常在使用时,可以搭配一个或多个Mixin扩展类。
GenericAPIView提供的关于序列化器使用的属性和方法
提供的关于序列化器使用的属性与方法
-
属性:
- serializer_class 指明视图使用的序列化器
-
方法:
-
get_serializer_class(self)
当出现一个视图类中调用多个序列化器时,那么可以通过条件判断在get_serializer_class方法中通过返回不同的序列化器类名就可以让视图方法执行不同的序列化器对象了。
返回序列化器类,默认返回
serializer_class,可以重写,例如:def get_serializer_class(self): if self.request.user.is_staff: return FullAccountSerializer return BasicAccountSerializer -
get_serializer(self, *args, **kwargs)
返回序列化器对象,主要用来提供给Mixin扩展类使用,如果我们在视图中想要获取序列化器对象,也可以直接调用此方法。
注意,该方法在提供序列化器对象的时候,会向序列化器对象的context属性补充三个数据:request、format、view,这三个数据对象可以在定义序列化器时使用。
- request 当前视图的请求对象
- view 当前请求的类视图对象
- format 当前请求期望返回的数据格式
-
提供的关于数据库查询的属性与方法
-
属性:
- queryset 指明使用的数据查询集
-
方法:
-
get_queryset(self)
返回视图使用的查询集,主要用来提供给Mixin扩展类使用,是列表视图与详情视图获取数据的基础,默认返回
queryset属性,可以重写,例如:def get_queryset(self): user = self.request.user return user.accounts.all() -
get_object(self)
返回详情视图所需的模型类数据对象,主要用来提供给Mixin扩展类使用。
在试图中可以调用该方法获取详情信息的模型类对象。
若详情访问的模型类对象不存在,会返回404。
该方法会默认使用APIView提供的check_object_permissions方法检查当前对象是否有权限被访问。
举例:
# url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view()), class BookDetailView(GenericAPIView): queryset = BookInfo.objects.all() serializer_class = BookInfoSerializer def get(self, request, pk): book = self.get_object() # get_object()方法根据pk参数查找queryset中的数据对象 serializer = self.get_serializer(book) return Response(serializer.data)
-
其他可以设置的属性
- pagination_class 指明分页控制类
- filter_backends 指明过滤控制后端
基于GenericAPIView写的五种接口
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)
from rest_framework import serializers from app01.models import Book class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = '__all__'
from django.contrib import admin from django.urls import path,re_path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), re_path(r'^books2/(?P<pk>\d)', views.BookGenericAPIView.as_view()), path('books2/', views.BooksGenericAPIView.as_view()), ]
from rest_framework.generics import GenericAPIView from rest_framework.response import Response from app01.ser import BookSerializer from app01.models import Book class BookGenericAPIView(GenericAPIView): # queryset 要传入queryset对象,需要查询的模型类 # serilaizer_class 使用那个序列化器来序列化这堆数据 # queryset = Book.objects.all() queryset = Book.objects serializer_class = BookSerializer def get(self,request,pk): book = self.get_object() book_ser = self.get_serializer(book) return Response(book_ser.data) def put(self,request,pk): book = self.get_object() book_ser = self.get_serializer(instance=book,data=request.data) if book_ser.is_valid(): book_ser.save() return Response(book_ser.data) else: return Response({'status':101,'message':'修改失败'}) def delete(self,request,pk): ret = self.get_object().delete() return Response({'status':100,'message':'删除成功'}) class BooksGenericAPIView(GenericAPIView): queryset = Book.objects serializer_class = BookSerializer def get(self,request): book = self.get_queryset() books_ser = self.get_serializer(instance=book,many=True) return Response(books_ser.data) def post(self,request): book_ser = self.get_serializer(data=request.data) if book_ser.is_valid(): book_ser.save() return Response(book_ser.data) else: return Response({'status':101,'message':'添加失败'})
基于GenericAPIView和五个视图扩展类写的接口
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)
from rest_framework import serializers from app01.models import Book class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = '__all__'
from django.contrib import admin from django.urls import path,re_path from app01 import views urlpatterns = [ re_path(r'^book3/(?P<pk>\d)', views.BookGenericView.as_view()), path('books3/',views.BooksGenericView.as_view()), ]
from rest_framework.generics import GenericAPIView from app01.ser import BookSerializer from app01.models import Book from rest_framework.mixins import ListModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin class BookGenericView(GenericAPIView,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin): 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) class BooksGenericView(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)
基于ModelViewSet编写5个接口
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)
from rest_framework import serializers from app01.models import Book class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = '__all__'
from django.contrib import admin from django.urls import path,re_path from app01 import views urlpatterns = [ re_path(r'^books4/(?P<pk>\d)', views.BookModelViewSet.as_view(actions={'get':'retrieve','put':'update','delete':'destroy'})), path('books4/',views.BookModelViewSet.as_view(actions={'get':'list','post':'create'})) # 当路径匹配,又是get请求,会执行Book5View的list方法 ]
from rest_framework.viewsets import ModelViewSet class BookModelViewSet(ModelViewSet): queryset = Book.objects serializer_class = BookSerializer
继承VIewSetMixin的视图类
源码分析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:对着create

1 自己封装一个CommonResponse对象,使用方法如下
return CoomonResponse('100','成功',boo_ser.data)
return CoomonResponse('101','验证失败',boo_ser.errors)
2 什么是正向代理,什么是反向代理
3 大家都写:分别用APIView,GenericAPIView,5个视图扩展类,GenericAPIView和5个视图扩展类写的接口和ModelViewSet写5个接口
4 今天讲的所有视图类的继承关系,写出来
浙公网安备 33010602011771号