如何在Django Rest Framework中将parameters字段转为单个对象
解决DRF中Parameters字段从列表转为单个对象的问题
问题背景
当前基于Django Rest Framework的API返回的JSON中,parameters字段是列表格式,但需求是改为单个对象格式。尝试将ParametersSerializer的many=True改为many=False后,返回的a/b/c/d值均为null。
问题原因
Batch模型和TeststripConfiguration是一对多关系(Batch通过teststrips关联多个TeststripConfiguration实例),当设置source='teststrips'且many=False时,DRF会把整个teststrips QuerySet传给ParametersSerializer,而不是单个TeststripConfiguration实例,导致序列化器无法正确读取a/b/c/d字段值。
解决方案
方案一:使用SerializerMethodField自定义获取逻辑
修改BatchSerializer中的parameters字段,通过SerializerMethodField手动获取第一个teststrip的参数:
class BatchSerializer(serializers.ModelSerializer): # 替换原parameters字段定义 parameters = serializers.SerializerMethodField() teststrips = TeststripSerializer(many=True, read_only=True) assay_type = serializers.SlugRelatedField( read_only=True, slug_field='name' ) product_id = serializers.ReadOnlyField() class Meta(): model = Batch fields = ('id', 'lot_no', 'product_id', 'assay_type', 'valid_from', 'expiry_date', 'is_active', 'last_modified', 'teststrips', 'parameters') def get_parameters(self, obj): # 获取第一个teststrip实例,序列化后返回单个对象 first_teststrip = obj.teststrips.first() if first_teststrip: return ParametersSerializer(first_teststrip).data return None
方案二:利用QuerySet的first()方法直接指定source
如果确定每个Batch至少有一个TeststripConfiguration实例,可以直接在source中使用teststrips.first():
class BatchSerializer(serializers.ModelSerializer): # 直接指定source为teststrips.first(),many=False parameters = ParametersSerializer(source='teststrips.first()', many=False, read_only=True) teststrips = TeststripSerializer(many=True, read_only=True) assay_type = serializers.SlugRelatedField( read_only=True, slug_field='name' ) product_id = serializers.ReadOnlyField() class Meta(): model = Batch fields = ('id', 'lot_no', 'product_id', 'assay_type', 'valid_from', 'expiry_date', 'is_active', 'last_modified', 'teststrips', 'parameters')
验证说明
两种方案都能将parameters字段转为单个对象格式,返回符合需求的JSON结构。如果存在Batch没有关联TeststripConfiguration的情况,方案一可以返回null,方案二会返回空对象,可根据业务场景选择。
内容的提问来源于stack exchange,提问作者JoeFrank
相关产品推荐
相关产品推荐

