drf视图家族

drf视图家族

视图家族 - 视图基类,视图工具类,工具视图类,视图集

视图基类:APIView、GenericAPIView

视图工具类:mixins包下的五个类(六个方法)

工具视图类:generics包下的所有GenericAPIView的子类

视图集:viewsets包下的类

generics中GenericAPIView使用

GenericAPIView基类(基本不会单独使用,了解即可,但是是高级视图类的依赖基础)

1)GenericAPIView继承APIView,所有APIView子类写法在继承GenericAPIView时可以保持一致

2)GenericAPIView将 queryset、serializer_class、lookup_field封装成类属性 

3)GenericAPIView给我们提供了三个方法 get_queryset、get_serializer、get_object

  • self.get_queryset() :获取所有
  • self.get_object() :获取根据pk获取单个
  • self.get_serializer(*args, **kwargs):获取指定
"""
GenericAPIView:额外的两个属性两个方法
filter_backends: 配置过滤类们
filter_queryset(): 调用配置的过滤类完成过滤(都是在群查接口中完成,传入queryset,接受过滤后的queryset)

pagination_class: 配置分页类
paginate_queryset(): 调用配置的分页类完成分页(都是在群查接口中完成,传入queryset,接受过滤后的queryset)
"""

mixins使用

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()),
]
View Code

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

 小结

    两个基类:APIView、GenericAPIVAPIView
        APIView:禁用csrf、解析、认证、渲染...
        GenericAPIVAPIView:禁用csrf、解析、认证、渲染... + 三个属性三个方法
        
    工具类:mixin包下的五个类,使用GenericAPIVAPIView的三个属性三个方法(过渡)
    
    工具视图类:mixin包下的类 + GenericAPIVAPIView 的组合形成的类
        配置三个属性 + 是否需要重写get、post等方法
    
    视图集:ViewSetMixin重写as_view方法,可以自定义 请求方式 - 响应函数 的映射关系
        配置三个属性 + mixin包下的类 + GenericViewSet
        ViewSet
原文地址:https://www.cnblogs.com/baohanblog/p/12343653.html