Loading

17.ViewSet和Router

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
 
没有绝对的好坏,使用哪种取决于你的需求

posted @ 2022-04-30 15:14  木子七  阅读(91)  评论(0编辑  收藏  举报