使⽤视图集ViewSet,可以将⼀系列逻辑相关的动作放到⼀个类中:
list() 提供⼀组数据
retrieve() 提供单个数据
create() 创建数据
update() 保存数据
destory() 删除数据
ViewSet视图集类不再实现get()、post()等⽅法,⽽是实现动作 action 如 list() 、create() 等。
视图集只在使⽤as_view()⽅法的时候,才会将action动作与具体请求⽅式对应上。如:
class NewsChannelViewSet(viewsets.ViewSet):
def list(self, request):
...
def retrieve(self, request):
...
在设置路由时,我们可以如下操作
urlpatterns = [
re_path(r'^channels/$', NewsChannelViewSet.as_view({
'get':'list'}),
re_path(r'^channels/(?P<pk>\d+)/$', NewsChannelViewSet.as_view({
'get': 'retrieve'})
]
一、action属性
在视图集中,我们可以通过action对象属性来获取当前请求视图集时的action动作是哪个。
def get_serializer_class(self):
if self.action == 'create':
return OrderCommitSerializer
else:
return OrderDataSerializer
二、常⽤视图集⽗类
1、ViewSet
继承⾃APIView,作⽤也与APIView基本类似,提供了身份认证、权限校验、流量管理等。
在ViewSet中,没有提供任何动作action⽅法,需要我们⾃⼰实现action⽅法。
2、GenericViewSet
继承⾃GenericAPIView,作⽤也与GenericAPIVIew类似,提供了get_object、get_queryset等⽅法便于列表视图与详情信息视图的开发。
3、ModelViewSet
继承⾃GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。
4、ReadOnlyModelViewSet
继承⾃GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin。
三、视图集中定义附加action动作
在视图集中,除了上述默认的⽅法动作外,还可以添加⾃定义动作。
添加⾃定义动作需要使⽤rest_framework.decorators.action
装饰器。
以action装饰器装饰的⽅法名会作为action动作名,与list、retrieve等同。

action装饰器可以接收两个参数:
methods: 该action⽀持的请求⽅式,列表传递
detail: 表示是action中要处理的是否是视图资源的对象(即是否通过url路径获取主键)
True 表示使⽤通过URL获取的主键对应的数据对象
False 表示不使⽤URL获取主键
定义视图:
class NewsChannelsAPIView(ListModelMixin,RetrieveModelMixin,GenericViewSet):
'''查询新增频道信息、修改频道名称'''
queryset=NewsChannel.objects.all()
serializer_class=NewsChannelSerializer
#detail为False表示不需要处理具体的NewsChannel对象
@action(methods=['get'],detail=False)
def latest(self,request):
channel_obj=self.get_queryset.latest('id')
serializer=self.get_serializer_class(instance=channel_obj)
return Response(serializer.data)
# detail为True,表示要处理具体与pk主键对应的NewsChannel对象
@action(methods=['put'],detail=True)
def channelName(self,request,pk):
channel_obj=self.get_object()
channel_obj.name=request.data.get('name')
channel_obj.save()
serializer=self.get_serializer_class(instance=channel_obj)
return Response(serializer.data)
定义路由:
urlpatterns=[
re_path('^channels/latest$',views.NewsChannelsAPIView(as_view({
'get':'latest'}))),
re_path('^channels/(?P<pk>\d+)/name/$', views.NewsChannelsAPIView.as_view({
'put':'channelName'})),
]
对于视图集ViewSet,我们除了可以⾃⼰⼿动指明请求⽅式与动作action之间的对应关系外,还可以使⽤Routers来帮助我们快速实现路由信息。
REST framework提供了两个router
SimpleRouter
DefaultRouter
使⽤⽅法:
1、创建router对象,并注册视图集
register(prefix,viewset,base_bane)
prefix:该视图集的路由前缀
viewset:视图集
base_name:路由名称的前缀
2、添加路由数据
可以有两种⽅式:
urlpatterns = [
...
]
urlpatterns += router.urls
或
urlpatterns = [
...
re_path(r'^', include(router.urls))
]
栗⼦如下:
from .views import NewsChannelsAPIView
router = routers.SimpleRouter()
router.register(r'channels',NewsChannelsAPIView,basename='channel')
urlpatterns = [
]
urlpatterns += router.urls
print(router.urls)
[
<URLPattern '^channels/$' [name='channel-list']>,
<URLPattern '^channels/latest/$' [name='channel-latest']>,
<URLPattern '^channels/(?P<pk>[^/.]+)/$' [name='channel-detail']>,
<URLPattern '^channels/(?P<pk>[^/.]+)/channelName/$' [name='channel-channelName']>
]