热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

4DjangoRESTFramework开发ViewSet

Afterroutinghasdeterminedwhichcontrollertouseforarequest,yourcontrollerisresponsibleformak

After routing has determined which controller to use for a request, your controller is responsible for making sense of the request and producing the appropriate output.

Routing 的职责是,决定哪一个 controller 应该对于收到的 request 做出回应,所以 controller 的作用是处理 request 并产生相对的 output 回应。
Aus


DRF 允许多个相关的 View 共同完善某个类的功能(多继承,类似 Java 的接口),并将诸多功能封装在单个类中,这样的类叫做 ViewSet。
一个 ViewSet 的类其实是某种 class-based View,该 View 不提供任何方法的 Handler 如:.get(), .post(), 但是提供 actions 如:.list(), .create()。 这些 actions 有助于使你的程序变得更加动态 (比如动态设置 Serilizer 会变得很方便)。
ViewSet 方法的 handler 则使用 .as_view()方法绑定到 View 的最终的相应操作上。一般 viewset 不在 urlconf 中配置,而是将其通过 router 类注册到应用程序上,router 会负责根据用户请求分发给相应 url。

相关知识点:ViewSetMixin
ViewSetMixin 重写 as_view 的信息,来达到定制路由的效果, 这个能让我们注册 url 变得更加简单。ViewSetMixin的源码部分如下:

1 class ViewSetMixin(object):
2 @classonlymethod
3 def as_view(cls, actions=None, **initkwargs):
4 ······
5 if not actions:
6 raise TypeError("The `actions` argument must be provided when "
7 "calling `.as_view()` on a ViewSet. For example "
8 "`.as_view({'get': 'list'})`")
9 ······


能看到在actions字段可以设置 {'get': 'list'} 这样的路由规则。

比如 urls.py 文件中配置:

my_product_list = ProductListViewSet.as_view({ 'get': 'list' })

另一种方法为创建 DefaultRouter 对象,然后用该对象注册 url。这种方法在工业中更被广泛地使用。

router = DefaultRouter()
router.register(r
'product', ProductListViewSet)

详见 Router 章节

ViewSetMixin 还有一个方法是initialize_request,这个方法主要是给 action 属性赋值,这个属性在设置动态 serializer 和 permission 的时候有很大的用处。

 

相关知识点 GenericViewSet:

GenericViewSet 类继承 GenericAPIView 和 ViewSetMixin,且提供了 get_object, get_queryset 方法以及其他的 generic view 的特征,但不会默认包括 action(所以需要通过继承特定类来实现)
在使用时必须重写该类,并且要么继承 mixin 类要么就自定义 action。

源码如下:

1 class GenericViewSet(ViewSetMixin, gernerics.GenericAPIView)
2 pass

由于 ViewSetMixin 类,这样继承了 GenericViewSet 的类就可以直接使用 router 对象配置 url 以及绑定 action。
由于 GenericAPIView 类, 这样继承了 GenericViewSet 的类就具有 queryset,serializer 以及 Pagination 的功能。

修改 views.py 文件:

1 class ProductListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
2 queryset = Product.objects.all()
3 serializer_class = ProductSerializer
4 pagination_class = ProductPagination

由于继承了 ListModelMixin 这样就自动有了 .list(request, *args, **kwargs) 的 action 方法。所以仅这段加上正确的 Router 配置,就可以实现展示商品 List 的效果。这也是它强于 GenericAPIView 的地方(即省略了 get -> list, post -> create 等函数的绑定)。

Extra 知识点 Routers:

由于 ViewSet 的 as_view() 方法,我们在 URL 配置时会简化很多操作,因为所有需要对 ViewSet 与 URL 的配置都可以使用 Router 类自动处理,这也使我们的代码变得更加规范。

例如:在 urls.py 文件中做下面操作:

1 from rest_framework.routers import DefaultRouter
2
3 router = DefaultRouter()
4 router.register(r'products', views.ProductListViewSet)
5
6 urlpatterns = [
7 url(r'^admin/', admin.site.urls),
8 url(r'^docs/', include_docs_urls(title="My Project")),
9 url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
10 url(r'^', include(router.urls)), # 所有在 router 对象上注册了的 ViewSet 都会被配置到 urlpatterns 中
11 ]

 在开发中 ViewSet 因为封装了大部分需要的操作,这些功能是它比 APIView 开发时更高效。一般只有在 ViewSet 的功能不够需要自定义一些特殊功能的时候,才会去自行编写稍微底层一点的 APIView 类。

转:https://www.cnblogs.com/crazy-chinese/p/9828138.html



推荐阅读
author-avatar
轰炸籹厕所744
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有