• 06_Tutorial 6: ViewSets & Routers 视图集与路由器


    1、Tutorial 6: ViewSets & Routers 视图集与路由器

    0、文档

    https://q1mi.github.io/Django-REST-framework-documentation/tutorial/6-viewsets-and-routers_zh/

    https://www.django-rest-framework.org/tutorial/6-viewsets-and-routers/

    源码参考 https://github.com/encode/rest-framework-tutorial

    1、viewsets.ReadOnlyModelViewSet

    ReadOnlyModelViewSet类来自动提供默认的“只读”操作

    不再需要向两个不同的类提供相同的信息

    from rest_framework import viewsets
    class UserViewSet(viewsets.ReadOnlyModelViewSet):       # 提供默认的“只读”操
        """
        此视图自动提供list与detail操作
        """
        queryset = User.objects.all()
        serializer_class = UserSerializer

     2、viewsets.ModelViewSet

    使用了ModelViewSet类来获取完整的默认的读写,增删改查操作

    class SnippetViewSet(viewsets.ModelViewSet):
        """
        此视图,自动提供,list,create,retrieve,update,和destroy操作
        此外,我们还提供一个额外的 highlight操作
        """
        queryset = Snippet.objects.all()
        serializer_class = SnippetSerializer
        permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
    
        # @detail_route(renderers_classes=[renderers.StaticHTMLRenderer])
        # 默认get请求, action 包含detail_route
        # url_path, 默认为函数name,  可以修改
        # url_name默认为函数name,替换('_', '-')    修改会报错
        @action(methods=['get'], detail=True, url_path='test', renderer_classes=[renderers.StaticHTMLRenderer])
        def highlight(self, request, *args, **kwargs):
            snippet = self.get_object()
            return Response(snippet.highlighted)
    
        def perform_create(self, serializer):       # 外键的POST操作,save
            serializer.save(owner=self.request.user)

    3、外键save

        def perform_create(self, serializer):       # 外键的POST操作,save
            serializer.save(owner=self.request.user)

    序列化是什么呢

    class SnippetSerializer(serializers.ModelSerializer):
    
        owner = serializers.ReadOnlyField(source='owner.username')        # source参数控制哪个属性用于填充字段
        # # 它包含一个url字段  该snippet的highlight
        # 单个字段,继承与HyperlinkedRelatedField
        highlight = serializers.HyperlinkedIdentityField(view_name='snippet-highlight', format='html')
    
        class Meta:
            model = Snippet
            fields = ['url', 'id', 'title', 'code', 'linenos', 'language', 'style', 'owner', 'highlight']

    4、action=detail_route + list_route

    @action装饰器创建了一个名为highlight的自定义操作。此装饰器可用于添加任何不符合标准创建/更新/删除样式的自定义端点

    默认情况下,使用@action装饰器的自定义操作将响应GET请求如果我们想要一个响应POST请求的操作,我们可以使用方法参数。

    默认情况下,自定义操作的url依赖于方法名称本身,希望更改url的构造方式,可以将url_path作为修饰符关键字参数包含进来。

    # 替换SnippetList,SnippetDetail和SnippetHighlight视图类
    from rest_framework.decorators import detail_route
    from rest_framework.decorators import action
    
    
    class SnippetViewSet(viewsets.ModelViewSet):
        """
        此视图,自动提供,list,create,retrieve,update,和destroy操作
        此外,我们还提供一个额外的 highlight操作
        """
        queryset = Snippet.objects.all()
        serializer_class = SnippetSerializer
        permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
    
        # @detail_route(renderers_classes=[renderers.StaticHTMLRenderer])
        # 默认get请求, action 包含detail_route
        # url_path, 默认为函数name,  可以修改
        # url_name默认为函数name,替换('_', '-')    修改会报错
        @action(methods=['get'], detail=True, url_path='test', renderer_classes=[renderers.StaticHTMLRenderer])
        def highlight(self, request, *args, **kwargs):
            snippet = self.get_object()
            return Response(snippet.highlighted)
    
        def perform_create(self, serializer):       # 外键的POST操作,save
            serializer.save(owner=self.request.user)

     5、lowb:将ViewSets绑定到URL

     我们是如何通过将http方法绑定到每个视图所需的操作,从每个ViewSet类创建多个视图的

    from snippets.views import SnippetViewSet, UserViewSet, api_root
    from rest_framework import renderers
    
    # 明确地将ViewSets绑定到URL
    snippet_list = SnippetViewSet.as_view({
        'get': 'list',
        'post': 'create'})
    snippet_detail = SnippetViewSet.as_view({
        'get': 'retrieve',
        'put': 'update',
        'path': 'partial_update',
        'delete': 'destroy'
    })
    snippet_highlight = SnippetViewSet.as_view({
        'get': 'highlight'
    }, renderer_classes=[renderers.StaticHTMLRenderer])
    user_list = UserViewSet.as_view({
        'get': 'list'
    })
    user_detail = UserViewSet.as_view({
        'get': 'retrieve'
    })
    
    urlpatterns
    = format_suffix_patterns([ path('', api_root), # 主index页面 path('snippets/', snippet_list, name='snippet-list'), # name用法,配合reverse('snippet-list') path('snippets/<int:pk>/', snippet_detail, name='snippet-detail'), path('snippets/<int:pk>/highlight/', snippet_highlight, name='snippet-highlight'), path('users/', user_list, name='user-list'), path('users/<int:pk>', user_detail, name='user-detail'), ])

    6、专业:使用路由器 Using Routers

    使用的是ViewSet而不是View类,我们实际上不需要自己设计URL

    将资源连接到视图和url的约定可以使用Router类自动处理

    我们需要做的就是使用路由器注册相应的视图集,然后让它执行其余操作。

    DefaultRouter类也会自动为我们创建API根视图

    ### 62使用路由器  Using Routers
    ###############
    # 我们使用的是ViewSet类而不是View类,我们实际上不需要自己设计URL
    from django.urls import path, include
    from rest_framework.routers import DefaultRouter
    from snippets import views
    
    # 创建路由器并注册我们的视图。
    router = DefaultRouter()
    router.register(r'snippets', views.SnippetViewSet)
    router.register(r'users', views.UserViewSet)
    
    urlpatterns = [
        path('', include(router.urls)),
    ]
    
    
    ##########
    # Tutorial 4: Authentication & Permissions
    ############
    # 可浏览API的登录和注销视图
    urlpatterns += [
        path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),  # restframework自带的urls
    ]
  • 相关阅读:
    【原】一张图片优化5K的带宽成本
    让手机站点像原生应用的四大途径
    iScroll4下表单元素聚焦及键盘的异常问题
    蜕变·WebRebuild 2013 前端年度交流会邀请
    【原】js实现复制到剪贴板功能,兼容所有浏览器
    【原】css实现两端对齐的3种方法
    【原】常见CSS3属性对ios&android&winphone的支持
    一枚前端开发-页面重构方向的招聘信息
    【原】分享超实用工具给大家
    【原】webapp开发中兼容Android4.0以下版本的css hack
  • 原文地址:https://www.cnblogs.com/venicid/p/12013520.html
Copyright © 2020-2023  润新知