17.ViewSet和Router

2022-12-29,,

REST框架为我们提高了一个更加抽象的ViewSet视图集,ViewSet提供一套自动的urlconf路由
ViewSet与View类几乎相同,不同之处在于它们提供诸如read或update之类的操作,而不是get、put等方法处理程序
ViewSet通常使用Router类来处理URL conf

一、使用ViewSets重构视图

导包:from rest_framework import viewsets

我们使用 ReadOnlyModelViewSet 类来自动提供默认的“只读”操作。我们仍然像使用常规视图那样设置 queryset 和 serializer_class 属性,但我们不再需要向两个不同的类提供相同的信息

#views.py

from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework import renderers class UserViewSet(viewsets.ReadOnlyModelViewSet):
"""
这个视图集会自动提供`list`和 `detail`操作
"""
queryset = User.objects.all()
serializer_class = UserSerializer
我们使用了 ModelViewSet 类来获取完整的默认读写操作。
请注意,我们还使用 @detail_route 装饰器创建一个名为 highlight 的自定义操作。这个
装饰器可用于添加不符合标准 create / update / delete 样式的任何自定义路径。
默认情况下,使用 @detail_route 装饰器的自定义操作将响应 GET 请求。如果我们想要一个
响应 POST 请求的动作,我们可以使用 methods 参数。
默认情况下,自定义操作的URL取决于方法名称本身。如果要更改URL的构造方式,可以为装饰
器设置url_path关键字参数。
class SnippetViewSet(viewsets.ModelViewSet):
permission_classes = (permissions.IsAuthenticatedOrReadOnly,) def perform_create(self, serializer): serializer.save(owner=self.request.user) '''
父类里面没有highlight方法,我们使用action装饰器
detail:是否查看详细
renderers_class:指定使用的解析器
'''
@action(detail=True,renderers_class=[renderers.StaticHTMLRenderer])
def highlight(self, request, *args, **kwargs):
snippet = self.get_object()
return Response(snippet.highlighted)

二、显式地将ViewSets绑定到URL路由上

#urls.py 初级写法
from snippets.views import SnippetViewSet,UserViewSet,api_root # 字典参数映射,例如使用get方法 就是 对应list操作
snippet_list = SnippetViewSet.as_view({
'get':'list',
'post':'create'
}) snippet_detail = SnippetViewSet.as_view({
'get': 'list',
'put': 'update',
'patch':'partial_update',
'delete':'destroy' }) urlpatterns = [
path('snippet/',snippet_list),
path('snippets/',snippet_detail) ]

三、使用DRF提供的路由Router

 from rest_framework.routers import DefaultRouter

# 实例化DefaultRouter
router = DefaultRouter()
# 通过router注册了两类url,snippets 和 users,而不是两条url
# router可以自动实现根路由
router.register(r'snippets',views.SnippetViewSet)
router.register(r'users',views.UserViewSet) urlpatterns = [
path('',include(router.urls))
]

四、三种视图编写方法之间的权衡

使用视图集可以最大程度的减少代码量,让你能够专注于API提供的交互和表示,而不是URLcon的细节,但这并不是说它就是最佳最好的解决方案吧,事实上,抽象的越多,可定制性就越低,适用场景就越少
三种视图的构建方法

基于函数的视图 @api_view
基于类的视图 APIView GenericView ListModelView
基于视图集的视图 ViewSet

 
没有绝对的好坏,使用哪种取决于你的需求

17.ViewSet和Router的相关教程结束。

《17.ViewSet和Router.doc》

下载本文的Word格式文档,以方便收藏与打印。