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,在继承的基础上实现了:
- 封装了序列化serializer_class以及查询集queryset的功能
配置了restframework.setting中的filter_backends,pagination_class,这样用户可以直接通过继承GenericAPIView,然后去重写筛选后端及数据分页功能,而在url端直接调用as_view方法,于base_view一致
重点是,可实现于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等方法绑定到适当的操作。
- 实现ListModelMixin中list方法于baseview中get请求的绑定,在接受get请求的时候,载入list方法。代码如下:
这样用户定制自己的view的时候,只需要继承ListAPIView的方法,就能实现get与list的绑定,以实现list内部的功能
GenericViewSet(viewset):
继承了GenericAPIView与ViewSetMixin两个类,目的也是为了实现get/post/put请求等于数据操作list/update/patch/delete等的绑定。
主要区别在于 mixins.xxxModelMixin与ViewSetMixin的区别,
ViewSetMixin摒弃了在类内部绑定的方式,而是允许设计者在url上进行动态绑定,结合url路由Router,而router内部实现这些绑 定。
- 手动绑定
<!-- 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'),
]
- 通过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)),
]