Drf官网教程(六) - ViewSet与Router
2018-06-24 本文已影响26人
dyq666
目录
- 使用ViewSet
- 使用Router
- url命名问题
- view和viewset的取舍
0. 概述
使用ViewSet的优势是自动化的url配置。
1. 使用ViewSet
-
更改User的view
from rest_framework import viewsets
class UserViewSet(viewsets.ReadOnlyModelViewSet):
"""
This viewset automatically provides `list` and `detail` actions.
"""
queryset = User.objects.all()
serializer_class = UserSerializer
ReadOnlyModelViewSet
提供了ACTION:LIST
& RETRIEVE
-
更改Snippet的view
from rest_framework.decorators import action
from rest_framework.response import Response
class SnippetViewSet(viewsets.ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
"""
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly,)
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
-
ModelViewSet
提供了所有的ACTION(5种)。 - 个人认为官网将高亮的view融入到这个viewset中,增加了学习成本,代码的可阅读性也不强,所以我只用ViewSet来完成最常用的功能,不改动其他特定的view。
- 更改url
snippet_list = views.SnippetViewSet.as_view({
'get': 'list',
'post': 'create'
})
snippet_detail = views.SnippetViewSet.as_view({
'get': 'retrieve',
'put': 'update',
'patch': 'partial_update',
'delete': 'destroy'
})
user_list = views.UserViewSet.as_view({
'get': 'list'
})
user_detail = views.UserViewSet.as_view({
'get': 'retrieve'
})
urlpatterns = format_suffix_patterns([
url(r'^$', views.api_root, name='api-index'),
url(r'^snippets/$', snippet_list, name='snippet-list'),
url(r'^snippets/(?P<pk>[0-9]+)/$', snippet_detail, name='snippet-detail'),
url(r'^snippets/(?P<pk>[0-9]+)/highlight/$', views.SnippetHighlight.as_view(), name='snippet-highlight'),
url(r'^users/$', user_list, name='user-list'),
url(r'^users/(?P<pk>[0-9]+)/$', user_detail, name='user-detail')
])
- 使用ViewSet后HTTP-METHOD与ACTION的映射就可以在
as_view
中完成。 - 在这里将所有
as_view
的配置都从url
提取出来用变量表示,然后再将变量作为url
的参数。
2. 使用Router
from django.conf.urls import url, include
from rest_framework.routers import DefaultRouter
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views
router = DefaultRouter()
router.register(r'snippets', views.SnippetViewSet)
router.register(r'users', views.UserViewSet)
specific_urlpatterns = format_suffix_patterns([
url(r'^snippets/(?P<pk>[0-9]+)/highlight/$', views.SnippetHighlight.as_view(), name='snippet-highlight'),
])
urlpatterns = [
url(r'^', include(router.urls))
] + specific_urlpatterns
- 不用再配置HTTP-METHOD与ACTION的映射。
- 由于我将特殊的view拆分出来(不像官网中将所有view都放入了viewset),所以先需要使用
format_suffix_patterns
来包裹这部分配置,然后在加上用Router配置的view。 - 现在可以删除
view.py
中的api_root了,Router会自动为提供api接口的主页。
3. url命名问题
使用Router后,我们之前为url命名的参数也就不存在了,但是在序列化类中,我们仍使用着url的命名来获取url,神奇的是整个api还在顺利的运行,具体只能是Router为我们按照一定的规则配置好了url的name
,在一番查找后我找到了下main的代码。
routers.SimpleRouter.get_urls()
如上图可知,url的
name
与我们之前写的相同仍是xxx-detail
。
4. view和viewset的取舍
ViewSet为我们提供了整齐划一的自动化url配置,也同时让我们的view更加清晰,但是同时也提高了自定义的参数的难度。