目录
一、views:视图基类
(一)APIView(回顾)
- 继承View类
- 重写as_view
- 重写dispatch
(二)GenericAPIView
- 继承APIView
- get_queryset方法:配置queryset类属性,提供视图类相关的Models
- queryset属性:获取queryset对象,最后要使用.all()方法转换成queryset对象,防止内部获取的为manage对象而出错
- get_serializer方法:配置serilaizer_class属性,提供视图类相关的序列化对象
- serializer_class属性:获取序列化对象,不能加括号(否则就是实例化类)
- get_object方法:在get_queryset基础上,配置lookup_url_kwarg属性,提供视图类相关的具体Model
- lookup_url_kwarg属性:默认为pk,url中有名分组名如果不为pk,需要重新定义
总结:GenericAPIView就是在APIView基础上额外提供了三个方法,三个类属性
from rest_framework.generic import GenericAPIView
class CarGenericAPIView(GenericAPIView):
# models.Car.object不是queryset对象,是manage对象,所以资源一定要在外部自己.all()
queryset = models.Car.object.filter(is_delete=False).all()
serialzier_class = serializers.CarModelSerializer
# lookup_url_kwargs = 'pk'
# 群查
def get(self,request,*args,**kwargs):
# 获取queryset对象
car_query = self.get_queryset()
#获取序列化对象
car_ser = self.get_serialzier(car_query,many=True)
return APIResponse(results = car_ser.data)
# 单查
def get(self,request,*args,**kwargs):
car_obj = self.get_object()
car_ser = self.get_serialzier(car_obj)
return APIResponse(results = car_ser.data)
二、mixins:视图工具类
- 要配合GenericAPIView类使用,将单查、群查、单增、整体单改、局部单改、单删六个接口操作封装成retrieve、list、create、update、partial_update、destroy六个方法
- 六个方法的实现体,调用的方法就是GenericAPIView提供的,所以要配合其使用
(一)CreateModelMixin
- 创建视图工具类,提供了create方法快速实现数据库单增操作,成功返回201状态码,数据验证失败返回400
from rest_framework.mixins import CreateModelMixin
from rest_framework.generic import GenericAPIView
class CarCreateGenericAPIView(CreateModelMixin,GenericAPIView):
queryset = models.Car.object.filter(is_delete=False).all()
serialzier_class = serializers.CarModelSerializer
# 单增
def post(self,request,*args,**kwargs):
return self.create(request,*args,**kwargs)
(二)ListModelMixin
- 群查视图工具类,提供了list方法快速实现群查操作,返回200状态码
- list方法也会对数据进行过滤和分页
from rest_framework.generic import GenericAPIView
from rest_framework.mixins import ListModelMixin
class CarListGenericAPIView(ListModelMixin,GenericAPIView):
queryset = models.Car.object.filter(is_delete=False).all()
serialzier_class = serializers.CarModelSerializer
# 群查
def get(self,request,*args,**kwargs):
return self.list(request,*args,**kwargs)
(三)RetrieveModelMixin
- 单查视图工具类,提供retrieve方法快速实现单查操作,存在返回202,否则404
from rest_framework.generic import GenericAPIView
from rest_framework.mixins import RetrieveModelMixin
class CarRetrieveGenericAPIView(RetrieveModelMixin,GenericAPIView):
queryset = models.Car.object.filter(is_delete=False).all()
serialzier_class = serializers.CarModelSerializer
# 单查
def get(self,request,*args,**kwargs):
return self.retrieve(request,*args,**kwargs)
(四)UpdateModelMixin
- update方法:可以快速实现一个数据对象的整体单改操作
- partial_update方法:可以快速实现一个数据对象的局部单改操作
- 修改视图工具类,成功返回200,数据校验失败返回400错误
from rest_framework.generic import GenericAPIView
from rest_framework.mixins import UpdateModelMixin
class CarUpdateGenericAPIView(UpdateModelMixin,GenericAPIView):
queryset = models.Car.object.filter(is_delete=False).all()
serialzier_class = serializers.CarModelSerializer
# 整体单改
def put(self,request,*args,**kwargs):
return self.update(request,*args,**kwargs)
# 局部单改
def patch(self,request,*args,**kwargs):
return self.partial_update(request,*args,**kwargs)
(五)DestroyModelMixin
- 删除视图工具类,提供了destroy方法快速实现一个数据对象的删除操作,成功返回204,不存在返回404
- 实际开发中,使用is_delete字段标记数据对象的删除,因此并不会用到该方法,需要重写该方法。
from rest_framework.generic import GenericAPIView
from rest_framework.mixins import DestroyModelMixin
class CarDeleteGenericAPIView(DestroyModelMixin,GenericAPIView):
queryset = models.Car.object.filter(is_delete=False).all()
serialzier_class = serializers.CarModelSerializer
# 单删
def put(self,request,*args,**kwargs):
return self.delete(request,*args,**kwargs)
三、generics:工具视图类
- 封装了不同个数和不同中的mixins与GenericAPIView的组合
- 不同的组合可以实现对应的get、post、put、patch、delete方法
- 使用时,只需配置三个属性即可:queryset、serializer_class和lookup_url_kwarg
from mrest_freamework.generics import RetrieveAPIView,ListAPIView
# (三)单查接口
class CarRetrieveAPIView(RetrieveAPIView):
queryset = models.Car.object.filter(is_delete=False).all()
serialzier_class = serializers.CarModelSerializer
# lookup_url_kwarg = 'pk'
# (二)群查接口
class CarListAPIView(ListAPIView):
queryset = models.Car.object.filter(is_delete=False).all()
serialzier_class = serializers.CarModelSerializer
# (九)单查、整体单改、局部单改、单删接口
from mrest_freamework.generics import RetrieveUpdateDestroyAPIView
class CarRetrieveUpdateDestroyAPIView(RetrieveUpdateDestroyAPIView):
queryset = models.Car.object.filter(is_delete=False).all()
serialzier_class = serializers.CarModelSerializer
(一)CreateAPIView
- 单增
- 封装了post方法
- 继承:CreateModelMixin,GenericAPIView
(二)ListAPIView
- 群查
- 封装了get方法
- 继承:ListModelMixin,GenericAPIView
(三)RetrieveAPIView
- 单查
- 封装了get方法
- 继承:RetrieveModelMixin,GenericAPIView
(四)DestoryAPIView
- 单删
- 封装了delete方法
- 继承:DestroyModelMixin,GenericAPIView
(五)UpdateAPIView
- 整体单改和局部单改
- 封装了put方法和patch方法
- 继承:UpdateModelMixin,GenericAPIView
(六)ListCreateAPIView
- 群查、单增
- 封装了get方法和post
- 继承:ListModelMixin,CreateModelMixin,GenericAPIView
(七)RetrieveUpdateAPIView
- 单查、整体单改、局部单改
- 封装了get、put、patch方法
- 继承:RetrieveModelMixin,UpdateModelMixin,GenericAPIView
(八)RetrieveDestroyAPIView
- 单查、单删
- 封装了get方法和delete方法
- 继承:RetrieveModelMixin,DestroyModelMixin,GenericAPIView
(九)RetrieveUpdateDestroyAPIView
- 单查、整体单改、局部单改、单删
- 封装了get、put、patch、delete方法
- 继承:RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView
四、viewsets:视图集
(一)工具类:ViewSetMixin
- 不继承任何类,重写了as_view方法,相比APIView的as_view方法,额外添加了一个参数actions
- actions属性:接收
as_view({'get':'list'})
中的{'get':'list'}
,从而将get请求映射到视图类的list函数 - 其他的视图集类都继承了ViewSetMixin类
(1)ViewSet
- 继承了
ViewSetMixin
和GenericAPIView
类 - 不提供get、put等方法,需要手动定义,应用于一些特定的发送post请求但是不用操作数据库的接口,比如:登录接口和短信验证码接口
(2)GenericViewSet
- 继承了
ViewSetMixin
和GenericAPIView
类 - 提供了get、put等方法,该分支严格满足资源接口
(三)视图集子类
(1)ReadOnlyModelViewSet
- 继承自
GenericViewSet
,同时包括了RetrieveModelMixin、ListModelMixin - 可以完成单查、群查两个接口
- 要在urls文件中配置as_view设置映射关系(actions接收)
# urls.py
urlpatterns=[
url(r'^v6/cars/$', views.CarReadOnlyAPIView.as_view({'get': 'list'})),
url(r'^v6/cars/(?P<pk>\d+)/$', views.CarReadOnlyAPIView.as_view({'get': 'retrieve'})),
]
from rest_framework.viewsets import ReadOnlyModelViewSet
class CarReadOnlyAPIView(ReadOnlyModelViewSett):
queryset = models.Car.objects.filter(is_delete=False).all()
serializer_class = serializers.CarModelSerializer
(2)ModelViewSet
- 继承自
GenericViewSet
,同时包括了CreateModelMixin、RetrieveModelMixin、UpdateModelMixin、DestroyModelMixin、ListModelMixin - 可以完成单增、单查、整体单改、局部单改、单删、群查六个接口
- 要在urls文件中配置as_view设置映射关系(actions接收)
# urls.py
urlpatterns=[
url(r'^v7/cars/$', views.CarModelViewSet.as_view({
'get': 'list',
'post': 'create',
})),
url(r'^v7/cars/(?P<pk>\d+)/$', views.CarModelViewSet.as_view({
'get': 'retrieve',
'put': 'update',
'patch': 'partial_update',
'delete': 'destroy',
})),
]
# views.py
from rest_framework.viewsets import ViewSetsMixin,GenericViewSet,ViewSet
class CarView(RetrieveModelMixin,ListModelMixin,GenericViewSet):
queryset = models.Car.object.filter(is_delete=False).all()
serialzier_class = serializers.CarModelSerializer
五、十大接口与路由层补充
(一)十大接口
- 通过重写继承解决响应结果没有数据状态码和状态信息的问题
- 通过重写delete方法解决根据is_delete字段值判断删除的问题
- 通过自定义和重写方法来解决没有群增、整体群改、局部群改、群删四个接口的问题
# urls.py
urlpatterns=[
url(r'^v7/cars/$', views.CarModelViewSet.as_view({
'get': 'list',
'post': 'create',
'put': 'many_update',
'patch': 'many_partial_update',
'delete': 'many_destroy',
})),
url(r'^v7/cars/(?P<pk>\d+)/$', views.CarModelViewSet.as_view({
'get': 'retrieve',
'put': 'update',
'patch': 'partial_update',
'delete': 'destroy',
})),
]
# 十大接口
class CarModelViewSet(ModelViewSet):
queryset = models.Car.object.filter(is_delete=False).all()
serialzier_class = serializers.CarModelSerializer
# 1. 通过重写继承解决响应结果没有数据状态码和状态信息的问题
def list(self,request,*args,**kwargs):
response = super().list(request,*args,**kwargs)
return APIRsponse(results = response.data)
# 2. 通过重写delete方法解决根据is_delete字段值判断删除的问题
def destroy(self,request,*args,**kwargs):
car_obj = self.get_object() # 如果获取失败,将会被异常模块捕捉
car_obj.is_delete = True
car_obj.save()
return APIView(msg='删除成功')
# 3.1 群删问题(定义many_destroy方法)
def many_destroy(self,request,*args,**kwargs):
###自己补充
# 3.2 整体群改问题(定义many_destroy方法)
def many_update(self,request,*args,**kwargs):
###自己补充
# 3.3 局部群改问题(定义many_detroy方法)
def many_partial_update(self,request,*args,**kwargs):
###自己补充
# 3.4 群增(重写create方法)
def create(self,request,*args,**kwargs):
if isinstance(reqeust.data,list):
car_ser = self.get_serialzier(data=reqeust.data,many=True)
car_ser.is_valid(raise_exception=True)
car_obj = car_ser.save()
return APIView(msg='群增成功',results=self.get_serialzier(car_obj,many=True).data )
return super().create(request,*args,**kwargs)
(二)路由层SimpleRouter类
该方法由drf提供
# urls.py
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register('v7/cars', views.CarModelViewSet, basename='car')
urlpatterns = [url(r'', include(router.urls))]
# urlpatterns.extend(router.urls)