六、DRF框架中的ViewSet
因为目前还是需要两个类才能实现所有接口,因为两个类中都有GET方法,所以想合并成一个就不能用这个请求方法名字,但Django框架不认识action(动作),就可以用到ViewSet
GenericAPIView只支持get、post、put、delete等请求方法,而不支持aciton,而ViewSet不支持get、post、put、delete等请求方法,只支持action
GenericViewSet
因为在Mixin中提供了action的方法,那么可以继承Mixin,而ModelViewSet就是继承了Mixin的各种方法(ListModelMixin、CreatModelMixin、RetrieveModelMixin、UpdateModelMixin、DestroyModelMixin),所以直接继承ModelViewSet即可
ReadOnlyModelViewSet:继承了RetrieveModelMixin和ListModelMixin,如果只需要获取数据的,直接继承这个就好
class ProjectViewSet(viewsets.ModelViewSet, viewsets.GenericViewSet): queryset = Projects.objects.all() serializer_class = serializers.ProjectModelSerializer filter_backends = [DjangoFilterBackend,OrderingFilter] filterset_fields = ['name', 'leader', 'tester'] ordering_fields = ['id', 'name', 'leader'] # 因为返回的字段往往是由序列化器中的fields来指定,那么如果还想要一个接口,只返回id和name,就要自定义action,首先在serializer文件再定义一个序列化器类(ProjectNamesModelSerializer),只返回id和name # 使用action装饰器来申明自定义动作 # 默认方法名就是动作名 # methods参数来指定该动作支持的请求方法,默认为get,可以支持多个 # detail参数用于指定该动作要处理的是否为详情数据(url是否需要传递pk主键),下面获取的是列表数据,如果获取详情数据(传ID值),那么需要指定detail为True,否则为False # url_name为路由别名,url_path为路由路径,一般不需要添加 @action(methods=['get'], detail=False, url_name="nn", url_path="mm") #路由中可用names来与请求方法对应,因为默认方法名就是动作名 def names(self, request, *args, **kwargs): #为什么不使用self.queryset是因为可能需要过滤后的数据而self.queryset是没有过滤的 queryset = self.get_queryset() serializer = self.get_serializer(instance=queryset, many=True) return Response(serializer.data) #get_serializer函数内部在调用get_serializer的时候会自动调用get_serializer_class def get_serializer_class(self, *args, **kwargs): #如果action为names的话就调用get_serializer_class return serializers.ProjectNamesModelSerializer if self.action == "names" else self.serializer_class
浙公网安备 33010602011771号