Drf/Django开发记录

Drf官网教程(六) - ViewSet与Router

2018-06-24  本文已影响26人  dyq666

目录

  1. 使用ViewSet
  2. 使用Router
  3. url命名问题
  4. view和viewset的取舍

0. 概述

使用ViewSet的优势是自动化的url配置。

1. 使用ViewSet

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

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)
  1. ModelViewSet提供了所有的ACTION(5种)。
  2. 个人认为官网将高亮的view融入到这个viewset中,增加了学习成本,代码的可阅读性也不强,所以我只用ViewSet来完成最常用的功能,不改动其他特定的view。
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')
])
  1. 使用ViewSet后HTTP-METHOD与ACTION的映射就可以在as_view中完成。
  2. 在这里将所有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
  1. 不用再配置HTTP-METHOD与ACTION的映射。
  2. 由于我将特殊的view拆分出来(不像官网中将所有view都放入了viewset),所以先需要使用format_suffix_patterns来包裹这部分配置,然后在加上用Router配置的view。
  3. 现在可以删除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更加清晰,但是同时也提高了自定义的参数的难度。

上一篇下一篇

猜你喜欢

热点阅读