视图集(ViewSets)

REST 框架的 ViewSets 允许开发人员集中精力对 API 的状态和交互进行建模,并根据常规约定自动处理 URL 构造。

ViewSet 类与 View 类几乎相同,不同之处在于它们提供诸如 readupdate 之类的操作,而不是 getput 等方法处理程序。

最后一个 ViewSet 类只绑定到一组方法处理程序,当它被实例化成一组视图的时候,通常通过使用一个 Router 类来处理自己定义 URL conf 的复杂性。




使用 ViewSets 重构

我们看一下目前的视图,把它们重构成视图集。

首先让我们将 UserListUserDetail 视图重构为一个 UserViewSet。我们可以删除这两个视图,并用一个类替换它们:

# apis.py

from django.contrib.auth.models import User
from myapp.serializers import UserSerializer
from rest_framework import viewsets # 视图集


class UserViewSet(viewsets.ReadOnlyModelViewSet):
    """
    此视图自动提供`list`和`detail`操作。
    (这里的文字会显示在 API 页面上)
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer

接下来类似的替换掉 BookListBookDetail

# apis.py

from rest_framework import viewsets # 视图集
from myapp.models import Book
from myapp.serializers import BookSerializer
from rest_framework import permissions # 权限模块
from myapp.permissions import IsOwnerOrReadOnly # 自定义权限


class BookViewSet(viewsets.ModelViewSet):
    """
    此视图自动提供`list`,`create`,`retrieve`,`update`和`destroy`操作。
    """
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                          IsOwnerOrReadOnly,)

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)




将 ViewSets 绑定到 URL

urls.py 文件中,我们将 ViewSet 类绑定到一组具体视图中。

# urls.py

from myapp.apis import BookViewSet, UserViewSet, api_root

book_list = BookViewSet.as_view({
    'get': 'list',
    'post': 'create'
})

book_detail = BookViewSet.as_view({
    'get': 'retrieve',
    'put': 'update',
    'patch': 'partial_update',
    'delete': 'destroy'
})

user_list = UserViewSet.as_view({
    'get': 'list'
})

user_detail = UserViewSet.as_view({
    'get': 'retrieve'
})

请注意,我们是如何通过将 http 方法绑定到每个视图所需的操作,从每个 ViewSet 类创建多个视图的。

现在我们将资源绑定到具体的视图中,我们可以像往常一样在 URL conf 中注册视图。

# urls.py

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    # API 根目录
    url(r'^api/$', api_root),

    # 所有 user 的 API
    url(r'^api/users/$', user_list, name='user-list'),
    # 单个 user 的 API
    url(r'^api/users/(?P<pk>[0-9]+)/$', user_detail, name='user-detail'),

    # 所有 book 的 API
    url(r'^api/books/$', book_list, name='book-list'),
    # 单个 book 的 API
    url(r'^api/book/(?P<pk>[0-9]+)/$', book_detail, name='book-detail'),
]




使用路由

因为我们使用的是 ViewSet 类而不是 View 类,我们实际上不需要自己设计 URL。将资源连接到视图和 url 的约定可以使用 Router 类自动处理。我们需要做的就是使用路由器注册相应的视图集,然后让它执行其余操作。

这是我们重写的 urls.py 文件。

from django.conf.urls import url
from django.contrib import admin
from rest_framework.routers import DefaultRouter

from myApp import apis


router = DefaultRouter()
router.register(r'^api/users', apis.UserViewSet)
router.register(r'^api/books', apis.BookViewSet)

urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

urlpatterns = urlpatterns + router.urls

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 132,310评论 18 139
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 10,489评论 4 57
  • 2016年6月26日,此时,我正坐在一个房间里面,房间里面有三个人,除了我,还有一对情侣。 我戴着耳机,里面单曲循...
    桃二汪阅读 285评论 0 2
  • 如果说《小狗钱钱1》是作者以小狗钱钱的口吻来教我们理财知识,建立其初步的理财系统和理财知识,那么《小狗钱钱2》一定...
    十八_阅读 73评论 0 0