(七) rest_framework GenericAPIView/GenericViewSet/ ModelViewSet 解析

GenericAPIView

对APIView进行封装,添加分页,获取queryset等方法。
GenericAPIView 总体来说只是把获取的方法赋值给类变量,需要时直接调用内部方法。

from rest_framework.generics import GenericAPIView
class AllAccounts(GenericAPIView):
    queryset = AccountModel.objects.all()
    serializer_class = AccountSerializers #解析器
    pagination_class = PageNumberPagination #分页器
    def get(self, request, *args, **kwargs):
        accounts = self.get_queryset()  #拿到数据
        """get_queryset:
         queryset = self.queryset
        if isinstance(queryset, QuerySet):
            queryset = queryset.all()
        return queryset
        """
        page_accounts = self.paginate_queryset(accounts)
        ser = self.get_serializer(page_accounts, many=True)
        #等于原始分页的方法 self.paginator.paginate_queryset(queryset, self.request, view=self)
        return Response(ser.data)

GenericViewSet

class GenericViewSet(ViewSetMixin, generics.GenericAPIView)
ViewSetMixin 内部重写as_view的方法。
不在从基类的路由映射request.method.lower()反转找到对应视图,而是直接字典路由匹配到视图函数。

for method, action in actions.items():
#actions为参数传递的字典
     handler = getattr(self, action)
setattr(self, method, handler)

#对应的路由映射写法:
    """
 # re_path(r"^accounts/$", views.AllAccounts.as_view(
 #     {'get': 'list', 'post': "create"}
 # ), name='accounts')
 
from rest_framework.viewsets import GenericViewSet
class AllAccounts(GenericViewSet):
    queryset = AccountModel.objects.all()
    serializer_class = AccountSerializers
    pagination_class = PageNumberPagination
    def list(self, request, *args, **kwargs):
        accounts = self.get_queryset()
        page_accounts = self.paginate_queryset(accounts)
        ser = self.get_serializer(page_accounts, many=True)
        return Response(ser.data)
        """
ModelViewSet

对mixins包下面常用的ListModelMixin, CreateModelMixin, DestroyModelMixin, RetrieveModelMixin 等类的继承。实现了增删改查的基本方法。
原始方法:

class AllAccounts(ListModelMixin, CreateModelMixin, DestroyModelMixin,RetrieveModelMixin , GenericViewSet):
    queryset = AccountModel.objects.all()
    serializer_class = ModelViewAccount
    pagination_class = PageNumberPagination

使用 modelviewset:

class AllAccounts(ModelViewSet):
    queryset = AccountModel.objects.all()
    serializer_class = ModelViewAccount
    pagination_class = PageNumberPagination

"""
    # re_path(r"^accounts/(?P<pk>w+)/$", views.AllAccounts.as_view(
    #     {'get': 'retrieve', 'delete': "destroy", "put": "partial_update"}
    # ), name='accounts_update'),
    # value对应的父类已经实现的视图函数。
"""
原文地址:https://www.cnblogs.com/donghaoblogs/p/12483576.html