REST框架包含了一个处理视图集的抽象,它允许开发人员集中精力建模API的状态和交互,并根据通用约定自动处理URL构造。
视图集类与视图类几乎相同,不同之处在于它们提供的是retrieve
或update
等操作,而不是get
或put
等方法。
一个ViewSet
类只在最后一刻被实例化为一组视图时,绑定的一组方法处理程序,通常是通过使用一个Router
类来处理定义URL conf的繁琐操作。
让我们获取当前的视图,并将它们重构为视图集。
首先,让我们将我们的StudentList
和StudentDetail
视图重构为一个StudentViewSet
。我们可以删除这两个视图,并用一个类替换它们:
class StudentViewSet(viewsets.ModelViewSet):"""This viewset automatically provides `list`, `create`, `retrieve`,`update` and `destroy` actions."""queryset = Student.objects.all()serializer_class = StudentSerializer
这里我们使用ModelViewSet
类自动提供完整的默认读和写操作集。我们仍然设置queryset
和serializer_class
属性,与使用常规视图时完全相同,但不再需要向两个单独的类提供相同的信息。
只有当我们定义URLConf时,处理程序方法才会绑定到对应的动作上。为了了解内部发生了什么,让我们首先从视图集中显式地创建一组视图。在crm/urls.py
文件中,我们将ViewSet
类绑定到一组具体的视图中。
from crm.views import StudentViewSet
from rest_framework import renderersstudent_list = StudentViewSet.as_view({'get': 'list','post': 'create'
})
student_detail = StudentViewSet.as_view({'get': 'retrieve','put': 'update','patch': 'partial_update','delete': 'destroy'
})
注意我们是如何从每个ViewSet类创建多个视图的,并为每个视图绑定所需要的http方法。
现在我们已经将资源绑定到具体的视图中,我们可以像往常一样用URL conf注册视图。
urlpatterns = format_suffix_patterns([path('students/', project_list, name='student-list'),path('students//', project_detail, name='student-detail'),
])
因为我们使用的是ViewSet类而不是View类,我们实际上不需要自己设计URL conf。使用路由器类,可以自动处理将资源连接到视图和绑定url。我们所需要做的就是注册合适的视图集给路由器,然后让它完成剩下的工作。
这是我们重新连接的crm/urls.py
文件。
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from projects import views# Create a router and register our viewsets with it.
router = DefaultRouter()
router.register(r'students', views.StudentViewSet)# The API URLs are now determined automatically by the router.
urlpatterns = [path('', include(router.urls)),
]
向路由器注册视图集类似于提供urlpattern。我们包含两个参数——视图的URL前缀和视图集本身。
我们正在使用的DefaultRouter
类也会自动为我们创建API根视图。
使用视图集是一种非常有用的抽象。它有助于确保你的API的URL约定的一致性,最小化你需要编写的代码量,并且允许你专注于你的API的交互和表示,而不是URL conf的细节。
这并不意味着它总是正确的方法。在使用基于类的视图而不是基于函数的视图时,也需要考虑类似的权衡。与单独构建视图相比,使用视图集不那么显式。