【DRF】视图集ViewSet和路由(8)

在这里插入图片描述
使⽤视图集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']>
]

猜你喜欢

转载自blog.csdn.net/YZL40514131/article/details/124680018