Loading

26.ViewSet和action

 
在dispatch过程中,下列属性可用于 ViewSet :
basename - 根url路径
action - 当前动作类型(例如 list , create ).
detail - 用于指示当前动作是针对一个列表还是一个对象detail的布尔指示器
suffix - viewset类型的前缀
name - viewset的名字
description - 详细描述
 
#可以用上面的属性做一些展示和跳转,例如
def get_func(self):
    # 通过action判断动作类型
    if self.action == 'list':
        '''get请求操作'''
    else:
        '''其他请求操作'''
 
VeiwSet视图集中,如果我们需要被路由用的额外方法,可以使用@action装饰器进行标记
# 导包
from rest_framework.decorators import action

@action()装饰器参数 
methods: 该action支持的请求方式,列表传递
detail: 表示是action中要处理的是否是视图资源的对象(即是否通过url路径获取主键)
        True 表示使用通过URL获取的字段对应的数据对象
        False 表示不使用URL获取字段
#示例 post请求  url路由: <int:pk>/set_password
from rest_framework.decorators import action
class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    @action(detail=True, methods=['post'])  
    def set_password(self, request, pk=None):  # 定义pk=None
        '''
        detail=True,从路由中获取pk字段。假设pk=test
        那么操作路径为 .../test/set_password
        '''
        user = self.get_object()
        serializer = PasswordSerializer(data=request.data)
        if serializer.is_valid():
            user.set_password(serializer.data['password'])
            user.save()
            return Response({'status': 'password set'})
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#示例 put和post请求 url路由:.../set_password
class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    @action(detail=False, methods=['post','put'])  
    def set_password(self, request):  
        '''
        detail=False,不从url中获取字段
        '''
        user = self.get_object()
        serializer = PasswordSerializer(data=request.data)
        if serializer.is_valid():
            user.set_password(serializer.data['password'])
            user.save()
            return Response({'status': 'password set'})
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
 
# action装饰器中也可以加其他额外参数,例如权限、限流等等

# 示例 增加权限验证
@action(detail=False, methods=['post','put'],permission_classes = [isAdminOrIsSelf])  
def set_password(self, request):  
 
小结
ViewSet
ViewSet 继承自 views.APIView 。可以使用任何父类属性,
如 permission_classes , authentication_classes 以便控制视图集上的 API 策略。
ViewSet 类不提供任何操作的实现。使用 ViewSet 类,需要重写该类并显式地定义动作实现。
GenericViewSet
GenericViewSet 类继承 GenericAPIView 
并提供 get_object ,get_queryset 方法和其他通用视图基本行为的默认配置,但默认情况不包括任何操作
ModelViewSet
ModelViewSet 又继承了 GenericAPIView ,但实现了基本的HTTP请求方法。
它提供 .list() , .retrieve() , .create() , .update() , .partial_update()和 .destroy() 操作。
这是我们真正使用的类,使用时至少需要提供queryset 和 serializer_class 属性的值。
可以使用父类GenericAPIView所有的方法
ReadOnlyModelViewSet
ReadOnlyModelViewSet 也继承 GenericAPIView 。与 ModelViewSet 相同的是,它也包
括一些动作的实现。不同的是但是只提供只读的 .list() 和 .retrieve() 动作
 

posted @ 2022-09-17 17:29  木子七  阅读(55)  评论(0编辑  收藏  举报