DRF get_serializer_class未执行 GET自定义action序列化器不符预期
DRF视图集自定义GET接口未触发序列化器选择逻辑问题
复现代码
编写的视图集代码如下:
class TenderViewSet(viewsets.ModelViewSet): """ API ViewSet for Propopsition """ queryset = models.Tender.objects.all() serializer_class = serializers.TenderGetSerializer def get_serializer_class(self): print('get_serializer_class passed') if self.action == 'map': self.serializer_class = serializers.TenderMapSerializer print('if passed') return super().get_serializer_class() @action(detail=True, methods=['get']) def map(self, request): print('action map passed') print(self.serializer_class) tenders = self.serializer_class.setup_eager_loading(models.Tender.objects.all()) serializer = serializers.TenderGetSerializer(tenders, many=True) return Response(serializer.data, status.HTTP_200_OK)
异常表现
访问自定义的map接口时,接口没有使用预期的TenderMapSerializer返回数据,反而加载了默认配置的TenderGetSerializer。重写的get_serializer_class方法全程未被调用,控制台也没有输出方法内定义的打印日志。
控制台实际运行输出:
action map passed <class 'tender.serializers.TenderGetSerializer'> HTTP GET /api/tenders/map/ 200 [0.19, 127.0.0.1:55247]
两个序列化器的逻辑区别:TenderGetSerializer会返回模型全部约20个字段,TenderMapSerializer仅返回业务需要的5个字段
排查记录
- 第一次修正尝试:将map方法内实例化序列化器的代码替换为
serializer = self.serializer_class(tenders, many=True),问题没有得到解决。 - 最终根因定位:
get_serializer_class方法仅会在POST类型的action中自动触发,该结论由L. Letovanec提供。
内容的提问来源于stack exchange,提问作者Mykhailo Kukol
相关产品推荐
相关产品推荐

