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)

 

 

posted on 2017-04-21 09:49  jingbostar  阅读(299)  评论(0编辑  收藏  举报

导航