zoukankan      html  css  js  c++  java
  • django-rest-framework学习之ViewSets & Routers--2017年4月19日至20日

    ViewSets & Routers
     
    参考链接:
    http://www.weiguda.com/blog/24/
    http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers/
    http://stackoverflow.com/questions/20550598/django-rest-framework-could-not-resolve-url-for-hyperlinked-relationship-using
     
    django-rst-framework为我们提供了ViewSet类, ViewSet为我们提供了默认的URL结构, 使得我们能更专注于API本身. ViewSet类与View类几乎是相同的, 但提供的是read或update, 而不是http动作get或put.
    一个ViewSet类最后仅仅绑定在一套method handlers上,当它被实例化成一套views时,用Router类可以处理复杂的URL配置
    ViewSet类在实例化后, 通过Router类, 最终将URL与ViewSet方法绑定. 接下来我们使用ViewSet代替之前的View.
    【1】用ViewSets重构
    把UserList和UserDetail重构成一个UserViewSet
    from rest_framework import viewsets
     
    class UserViewSet(viewsets.ReadOnlyModelViewSet):
        """
        This viewset automatically provides `list` and `detail` actions.
        """
        queryset = User.objects.all()
        serializer_class = UserSerializer
     
    把MyLessonList,MyLessonDetail,MyLessonHighlight重构成一个MyLessonViewSet
    from rest_framework.decorators import detail_route
     
    class MyLessonViewSet(viewsets.ModelViewSet):
        """
        This viewset automatically provides 'list', 'create', 'retrieve',
        'update' and 'destroy' actions.
     
        Additionally we also provide and extra 'highlight' action.
        """
        queryset = MyLesson.objects.all()
        serializer_class = MyLessonSerializer
        permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                              IsOwnerOrReadOnly,)
     
        @detail_route(renderer_classes=[renderers.StaticHTMLRenderer])
        def highlight(self,request,*args,**kwargs):
            myLesson = self.get_object()
            return Response(myLesson.highlighted)
     
        def perform_create(self,serializer):
            serializer.save(owner=self.request.user)
    使用@detail_route装饰器来创建一个自定义操作highlight,可以加methods参数,限定http方法
    ,默认是get,url是默认生成的,如果想自定义,可以加url_path参数
     
    【2】绑定ViewSets到特定的URLS
     
    from django.conf.urls import url,include
    from myLesson.views import MyLessonViewSet,UserViewSet,api_root
    from rest_framework import renderers
    from rest_framework.urlpatterns import format_suffix_patterns
     
    myLesson_list = MyLessonViewSet.as_view({
        'get':'list',
        'post':'create'
    })
     
    myLesson_detail = MyLessonViewSet.as_view({
        'get':'retrieve',
        'put':'update',
        'patch':'partial_update',
        'delete':'destroy'
    })
     
    myLesson_highlight = MyLessonViewSet.as_view({
        'get':'highlight'
    },renderer_classes=[renderers.StaticHTMLRenderer])
     
    user_list = UserViewSet.as_view({
        'get':'list'
    })
    user_detail = UserViewSet.as_view({
        'get':'retrieve'
    })
     
     
    urlpatterns = [
        url(r'^$',api_root),
        url(r'^users/$',user_list,name='user-list'),
        url(r'^users/(?P<pk>[0-9]+)/$',user_detail,name='user-detail'),
        url(r'^myLesson/$',myLesson_list,name='myLesson-list'),
        url(r'^myLesson/(?P<pk>[0-9]+)/$',myLesson_detail,name='myLesson-detail'),
        url(r'^myLesson/(?P<pk>[0-9]+)/highlight/$',myLesson_highlight,name='myLesson-highlight'),
    ]
     
    urlpatterns = format_suffix_patterns(urlpatterns)
     
    我们ViewSet创建了很多VIew,通过绑定http方法给每个view特定的动作
     
    【3】使用Routers
    我们实际上是没必要设计URL的,可以使用Routers自动化的配置,DefaultRouter可以自动化创建根view,所以可以删除api_root
    from django.conf.urls import url, include
    from snippets import views
    from rest_framework.routers import DefaultRouter
     
    # Create a router and register our viewsets with it.
    router = DefaultRouter()
    router.register(r'snippets', views.MyLessonViewSet)
    router.register(r'users', views.UserViewSet)
     
    # The API URLs are now determined automatically by the router.
    # Additionally, we include the login URLs for the browsable API.
    urlpatterns = [
        url(r'^', include(router.urls)),
        url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
    ]
     
    【4】权衡views和viewsets
    viewsets自动创建URL,减少代码,但是使用views更加精确
     
    【5】修改完代码,myLesson和user页面均报错
    修改方式,在serializers.py中将有view_name的serializers.HyperlinkedIdentityField行都去掉。用Router方式自自动生成url,不清楚view_name怎么定义。因此highlight做不了超链接,调了两天不清楚怎么办,搁置了。。。。
    url = serializers.HyperlinkedIdentityField(view_name="user-detail")
    myLesson = serializers.HyperlinkedRelatedField(many=True,view_name='MyLesson-detail'    ,read_only=True)
     
  • 相关阅读:
    第四章 源代码的下载和编译 读书笔记
    第三章 Git使用入门 读书笔记
    第二章 搭建Android开发环境 读书笔记
    第一章Android系统移植与驱动开发概述 读书笔记
    读书笔记第九章
    读书笔记第八章
    读书笔记第十章
    读书笔记第七章
    读书笔记第五章
    读书笔记第六章
  • 原文地址:https://www.cnblogs.com/jingbostar/p/6742011.html
Copyright © 2011-2022 走看看