wintershii 2020-02-22
视图家族 - 视图基类,视图工具类,工具视图类,视图集
视图基类:APIView、GenericAPIView
视图工具类:mixins包下的五个类(六个方法)
工具视图类:generics包下的所有GenericAPIView的子类
视图集:viewsets包下的类
GenericAPIView基类(基本不会单独使用,了解即可,但是是高级视图类的依赖基础)
1)GenericAPIView继承APIView,所有APIView子类写法在继承GenericAPIView时可以保持一致
2)GenericAPIView将 queryset、serializer_class、lookup_field封装成类属性
3)GenericAPIView给我们提供了三个方法 get_queryset、get_serializer、get_obj
mixins包存放了视图工具类(不能单独使用,必须配合GenericAPIView使用)
""" CreateModelMixin:单增工具类 create方法 ListModelMixin:群查工具类 list方法 RetrieveModelMixin:单查工具类 retrieve方法 UpdateModelMixin:单整体局部改工具类 update方法 DestroyModelMixin:单删工具类 destory方法 """ """ generics包下的所有GenericAPIView的子类(就是继承GenericAPIView和不同mixins下的工具类的组合) 1)定义的视图类,继承generics包下已有的特点的GenericAPIView子类,可以在只初始化queryset和serializer_class两个类属性后,就获得特定的功能 2)定义的视图类,自己手动继承GenericAPIView基类,再任意组合mixins包下的一个或多个工具类,可以实现自定义的工具视图类,获得特定的功能或功能们 注: i)在这些模式下,不能实现单查群查共存(可以加逻辑区分,也可以用视图集知识) ii)DestroyModelMixin工具类提供的destory方法默认是从数据库中删除数据,所以一般删除数据的需求需要自定义逻辑 """
urls.py
from django.conf.urls import url from . import views urlpatterns = [ # ... url(r‘^v1/books/$‘, views.BookV1APIView.as_view()), url(r‘^v1/books/(?P<pk>\d+)/$‘, views.BookV1APIView.as_view()), url(r‘^v2/books/$‘, views.BookV2APIView.as_view()), url(r‘^v2/books/(?P<pk>\d+)/$‘, views.BookV2APIView.as_view()), url(r‘^v3/books/$‘, views.BookV3APIView.as_view()), url(r‘^v3/books/(?P<pk>\d+)/$‘, views.BookV3APIView.as_view()), ]
views.py
# ----------------------------- 过渡写法:了解 ----------------------------- from rest_framework.generics import GenericAPIView class BookV1APIView(GenericAPIView): # 将数据和序列化提升为类属性,所有的请求方法都可以复用 queryset = models.Book.objects.filter(is_delete=False).all() serializer_class = serializers.BookModelSerializer lookup_field = ‘pk‘ # 可以省略,默认是pk,与url有名分组对应的 # 群查 def get(self, request, *args, **kwargs): # queryset = models.Book.objects.filter(is_delete=False).all() # => 拆分成方法+属性两行代码 queryset = self.get_queryset() # serializer = serializers.BookModelSerializer(instance=queryset, many=True) # => 拆分成方法+属性两行代码 serializer = self.get_serializer(instance=queryset, many=True) return APIResponse(results=serializer.data) # 单查 # def get(self, request, *args, **kwargs): # obj = self.get_object() # serializer = self.get_serializer(obj) # return APIResponse(results=serializer.data) # 单增 def post(self, request, *args, **kwargs): # serializer = serializers.BookModelSerializer(data=request.data) serializer = self.get_serializer(data=request.data) # 同样的步骤多了,好处就来了 serializer.is_valid(raise_exception=True) obj = serializer.save() return APIResponse(result=self.get_serializer(obj).data, http_status=201) # ----------------------------- 过渡写法2:了解 ----------------------------- from rest_framework.generics import GenericAPIView from rest_framework import mixins class BookV2APIView(GenericAPIView, mixins.RetrieveModelMixin, mixins.CreateModelMixin): queryset = models.Book.objects.filter(is_delete=False).all() serializer_class = serializers.BookModelSerializer # 单查 def get(self, request, *args, **kwargs): # obj = self.get_object() # serializer = self.get_serializer(obj) # return APIResponse(results=serializer.data) # return self.retrieve(request, *args, **kwargs) response = self.retrieve(request, *args, **kwargs) return APIResponse(result=response.data) # 单增 def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) # ----------------------------- 开发写法:常用 ----------------------------- from rest_framework.generics import RetrieveAPIView class BookV3APIView(RetrieveAPIView): queryset = models.Book.objects.filter(is_delete=False).all() serializer_class = serializers.BookModelSerializer # 单查 pass