You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST Framework对象字段序列化疑问:如何像ORM关联查询一样指定子对象字段

解决DRF中类似ORM双下划线的子字段序列化需求

嘿,我懂你想要的那种清爽写法——就像ORM里用双下划线跨表关联查询那样,不用额外定义嵌套序列化器,直接指定子对象的单个字段对吧?其实DRF里确实有对应的实现方式,给你分享两种最常用的:

方法一:用source参数+双下划线(最贴合你的需求)

DRF的字段支持通过source参数指定数据源,而且同样支持ORM风格的双下划线关联,完美匹配你想要的用法。如果只是想获取子对象的title字段列表,可以直接在序列化器里定义一个新字段,用source指向关联对象的字段:

class GarageSerializer(serializers.ModelSerializer):
    # 用双下划线直接关联car_set的title字段,many=True表示是多个对象
    car_titles = serializers.CharField(source='car_set__title', many=True)
    
    class Meta:
        model = Garage
        fields = ('id', 'title', 'address', 'car_titles')

这样序列化后返回的结果会是:

{
    "id": 1,
    "title": "MyGarage",
    "address": "Paris",
    "car_titles": ["Lamborghini"]
}

如果你的Car模型的__str__方法刚好返回title,还可以用更简洁的StringRelatedField:

car_titles = serializers.StringRelatedField(many=True, source='car_set')

效果和上面完全一样,不过这种方式依赖模型的__str__实现,适合已经定义好的场景。

方法二:用SerializerMethodField(更灵活)

如果需要对返回的子字段做额外处理(比如过滤空值、格式化内容),SerializerMethodField会更适合,你可以自定义逻辑来获取需要的字段:

class GarageSerializer(serializers.ModelSerializer):
    car_titles = serializers.SerializerMethodField()
    
    # 方法名固定为get_<字段名>,obj是当前序列化的Garage实例
    def get_car_titles(self, obj):
        # 这里可以加任何你需要的逻辑,比如过滤掉title为空的车
        return [car.title for car in obj.car_set.all() if car.title]
    
    class Meta:
        model = Garage
        fields = ('id', 'title', 'address', 'car_titles')

这种方式自由度更高,适合复杂场景,但写法比第一种稍繁琐。

对比你之前的嵌套序列化器写法,这两种方式都不用额外定义子序列化器,更符合你想要的"类似ORM双下划线"的简洁风格,根据你的实际需求选就行~

内容的提问来源于stack exchange,提问作者sk schoolboy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 14:07:43