视图集(ViewSets)

2018-04-20  本文已影响110人  SingleDiego

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
上一篇 下一篇

猜你喜欢

热点阅读