• 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)
     
  • 相关阅读:
    洛谷P2219 [HAOI2007]修筑绿化带(单调队列)
    CF1059E Split the Tree(倍增)
    CF1059D Nature Reserve(二分)
    洛谷P4199 万径人踪灭(manacher+FFT)
    洛谷P2515 [HAOI2010]软件安装(tarjan缩点+树形dp)
    洛谷P4867 Gty的二逼妹子序列(莫队+树状数组)
    CF932E Team Work(第二类斯特林数)
    JZOJ4307. 【NOIP2015模拟11.3晚】喝喝喝
    洛谷 P2519 [HAOI2011]problem a
    构建秘钥对验证的SSH体系
  • 原文地址:https://www.cnblogs.com/jingbostar/p/6742011.html
Copyright © 2020-2023  润新知