django-rest-framework的各类view关联与差异

django-rest-framework的各类view关联与差异

继承关系

以下依次向下继承

GenericViewSet(viewset)         -----> drf

    GenericAPIView(generics)    -----> drf

        APIView(views)          -----> drf

            View                -----> django 

各种View之间的差异

取决要点

mixin:
    CreateModelMixin
    ListModelMixin
    RetrieveModelMixin
    UpdateModelMixin
    DestroyModelMixin

实现主要的原理:

view: 本身是django自带的base.view,具有as_view()的方法来绑定url,以及一些基本类视图定义的方法.

APIView: django_rest_framework封装的view,对view进行了一层封装,在实现base-view的基础上,重写了as_view()方法,在base-view的基础上增加了如下一些配置

renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
metadata_class = api_settings.DEFAULT_METADATA_CLASS
versioning_class = api_settings.DEFAULT_VERSIONING_CLASS

并定义了对应的方法.

下面两个View类是开发应用中的重点

GenericAPIView(generics): 继承自APIView,在继承的基础上实现了:

  1. 封装了序列化serializer_class以及查询集queryset的功能
  2. 配置了restframework.setting中的filter_backends,pagination_class,这样用户可以直接通过继承GenericAPIView,然后去重写筛选后端及数据分页功能,而在url端直接调用as_view方法,于base_view一致

  3. 重点是,可实现于mixin的结合实现多样的功能:

    • 实现ListModelMixin中list方法于baseview中get请求的绑定,在接受get请求的时候,载入list方法。代码如下:
       class ListAPIView(mixins.ListModelMixin,
                        GenericAPIView):
          """
          Concrete view for listing a queryset.
          """
          def get(self, request, *args, **kwargs):
              return self.list(request, *args, **kwargs)

    用于mixin的ModelMixin与GenericAPIView进行绑定基类提供核心功能,mixin类提供.list()和.create()操作。然后,我们明确地将方法get和post等方法绑定到适当的操作。

这样用户定制自己的view的时候,只需要继承ListAPIView的方法,就能实现get与list的绑定,以实现list内部的功能

GenericViewSet(viewset):
继承了GenericAPIView与ViewSetMixin两个类,目的也是为了实现get/post/put请求等于数据操作list/update/patch/delete等的绑定。

主要区别在于 mixins.xxxModelMixin与ViewSetMixin的区别,
ViewSetMixin摒弃了在类内部绑定的方式,而是允许设计者在url上进行动态绑定,结合url路由Router,而router内部实现这些绑 定。

  1. 手动绑定
<!--        view        -->
class GoodsListViewset(viewsets.GenericViewSet):
    """
    List all goods/商品列表页
    """
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = StandardResultsSetPagination


<!--    url         -->
#手动实现get-list(方法-数据对象)的绑定到url
goods_list = GoodsListViewset.as_view({
    #绑定关系
    'get': 'list',
})

urlpatterns = [
url(r'^', goods_list,name='goods_list'),
]
  1. 通过router(路由器)注册
<!--            view            -->
class GoodsListViewset(mixins.ListModelMixin,viewsets.GenericViewSet):
    """
    List all goods/商品列表页
    """
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = StandardResultsSetPagination

<!--            url         -->
#goods url configure
router = DefaultRouter()
# DefaultRouter实例注册url
router.register(r'goods', GoodsListViewset)
urlpatterns = [
url(r'^', include(router.urls)),
]

猜你喜欢

转载自blog.csdn.net/newbietan/article/details/80037580