• Django REST framework -- ViewSets & Routers


    ViewSets & Routers

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

    ViewSets是对模型的高度抽象, 让开发者聚焦于建模状态, 和 接口的交互, 基于通用的规则构建URL.

    REST framework includes an abstraction for dealing with ViewSets, that allows the developer to concentrate on modeling the state and interactions of the API, and leave the URL construction to be handled automatically, based on common conventions.

    ViewSet classes are almost the same thing as View classes, except that they provide operations such as retrieve, or update, and not method handlers such as get or put.

    A ViewSet class is only bound to a set of method handlers at the last moment, when it is instantiated into a set of views, typically by using a Router class which handles the complexities of defining the URL conf for you.

    Refactoring to use ViewSets

    定义非常简单,无需关注 get post接口。

    Here we've used the ReadOnlyModelViewSet class to automatically provide the default 'read-only' operations. We're still setting the queryset and serializer_class attributes exactly as we did when we were using regular views, but we no longer need to provide the same information to two separate classes.

    from rest_framework import viewsets
    
    class UserViewSet(viewsets.ReadOnlyModelViewSet):
        """
        This viewset automatically provides `list` and `retrieve` actions.
        """
        queryset = User.objects.all()
        serializer_class = UserSerializer

    可以自定义action。

    This time we've used the ModelViewSet class in order to get the complete set of default read and write operations.

    Notice that we've also used the @action decorator to create a custom action, named highlight. This decorator can be used to add any custom endpoints that don't fit into the standard create/update/delete style.

    Custom actions which use the @action decorator will respond to GET requests by default. We can use the methods argument if we wanted an action that responded to POST requests.

    from rest_framework.decorators import action
    from rest_framework.response import Response
    from rest_framework import permissions
    
    class SnippetViewSet(viewsets.ModelViewSet):
        """
        This viewset automatically provides `list`, `create`, `retrieve`,
        `update` and `destroy` actions.
    
        Additionally we also provide an extra `highlight` action.
        """
        queryset = Snippet.objects.all()
        serializer_class = SnippetSerializer
        permission_classes = [permissions.IsAuthenticatedOrReadOnly,
                              IsOwnerOrReadOnly]
    
        @action(detail=True, renderer_classes=[renderers.StaticHTMLRenderer])
        def highlight(self, request, *args, **kwargs):
            snippet = self.get_object()
            return Response(snippet.highlighted)
    
        def perform_create(self, serializer):
            serializer.save(owner=self.request.user)

    Binding ViewSets to URLs explicitly

    对于一个viewsets可以定义多个视图。

    from snippets.views import SnippetViewSet, UserViewSet, api_root
    from rest_framework import renderers
    
    snippet_list = SnippetViewSet.as_view({
        'get': 'list',
        'post': 'create'
    })
    snippet_detail = SnippetViewSet.as_view({
        'get': 'retrieve',
        'put': 'update',
        'patch': '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'
    })

    绑定到不同的url

    urlpatterns = format_suffix_patterns([
        path('', api_root),
        path('snippets/', snippet_list, name='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')
    ])

    Using Routers

    使用router进行注册。

    from django.urls import path, include
    from rest_framework.routers import DefaultRouter
    from snippets import views
    
    # Create a router and register our viewsets with it.
    router = DefaultRouter()
    router.register(r'snippets', views.SnippetViewSet)
    router.register(r'users', views.UserViewSet)
    
    # The API URLs are now determined automatically by the router.
    urlpatterns = [
        path('', include(router.urls)),
    ]

    Trade-offs between views vs viewsets

    保证API一致性

    减少书写的代码

    使得你聚焦于API交互和表示

    Using viewsets can be a really useful abstraction. It helps ensure that URL conventions will be consistent across your API, minimizes the amount of code you need to write, and allows you to concentrate on the interactions and representations your API provides rather than the specifics of the URL conf.

    That doesn't mean it's always the right approach to take. There's a similar set of trade-offs to consider as when using class-based views instead of function based views. Using viewsets is less explicit than building your views individually.

    View继承图

    https://testdriven.io/blog/drf-views-part-3/

    https://mrcoles.com/django-rest-framework-abstraction-grid/

    Django REST Framework Views Series:

    1. APIViews
    2. Generic Views
    3. ViewSets

    https://testdriven.io/blog/drf-views-part-1/

    https://testdriven.io/blog/drf-views-part-2/

    https://testdriven.io/blog/drf-views-part-3/

    出处:http://www.cnblogs.com/lightsong/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
  • 相关阅读:
    搭建Vmware Workstation 12 + Kylin 4.02(Ubuntu 16.04) + petalinux + Vivado
    dash 和 bash 切换
    centos的镜像下载
    docker部署redis,kafka
    Centos7下使用mail发送邮件配置
    实现内网主机既能访问yum源,又能curl通baidu,外网nginx的配置
    centos7下使用mysql离线安装包安装mysql5.7
    内网主机使用nginx代理访问阿里yum源
    配置阿里云yum源
    centos下查看cpu核数
  • 原文地址:https://www.cnblogs.com/lightsong/p/15400242.html
Copyright © 2020-2023  润新知