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

在Django Rest Framework中直接映射深层嵌套JSON至单模型的方法

问题:直接映射两层嵌套的API数据到单个模型序列化器

我需要序列化一个包含location字典的geometry字典(数据来自外部API,嵌套两层),并将其值映射到单个模型。目前通过source='*'实现,但需要为每个嵌套对象新建ModelSerializer,请问是否有方法直接定位到目标嵌套对象?

示例输入数据

{
    ...
    "geometry": {
        "location": {
            "lat": ...,
            "lng": ...,
         }
    }
    ...
}

对应的模型

class MyModel(models.Model):
    # 其他一级属性
    latitude = models.CharField(max_length=20)
    longitude = models.CharField(max_length=20)

当前序列化器实现

class GeometrySerializer(serializers.ModelSerializer):
    latitude = serializers.DecimalField(max_digits=globals.MAX_DECIMAL_DIGITS, decimal_places=globals.MAX_DECIMAL_PLACES)
    longitude = serializers.DecimalField(max_digits=globals.MAX_DECIMAL_DIGITS, decimal_places=globals.MAX_DECIMAL_PLACES)

    class Meta:
        model = models.Location
        fields = ['latitude', 'longitude']

class GeometryLocationSerializer(serializers.ModelSerializer):
    location = GeometrySerializer(source='*')

    class Meta:
        model = models.Location
        fields = ['location']


class LocationSerializer(serializers.ModelSerializer):
    # 注释掉的直接映射尝试
    # latitude = serializers.DecimalField(max_digits=globals.MAX_DECIMAL_DIGITS, decimal_places=globals.MAX_DECIMAL_PLACES, source='geometry.location.lat')
    # longitude = serializers.DecimalField(max_digits=globals.MAX_DECIMAL_DIGITS, decimal_places=globals.MAX_DECIMAL_PLACES, source='geometry.location.lng')
    geometry = GeometryLocationSerializer(source='*')

    class Meta:
        model = models.Location
        fields = ['id', 'addr_address', 'business_status', 'formatted_address', 'formatted_phone_number', 'icon', 'icon_background_color', 'icon_mask_base_uri',
                        'international_phone_number', 'name', 'place_id', 'rating', 'reference', 'url', 'user_ratings_total', 'vicinity', 'website', 'geometry',
                        'compound_code', 'global_code']
        read_only_fields = ['id']

解决方案

完全不需要创建多层嵌套的ModelSerializer,直接在主序列化器中给latitude和longitude字段指定嵌套路径的source即可,直接从两层嵌套结构中取值映射到模型字段,省去额外序列化器的冗余代码。

修改后的序列化器代码:

class LocationSerializer(serializers.ModelSerializer):
    # 直接通过source定位到两层嵌套的字段
    latitude = serializers.DecimalField(
        max_digits=globals.MAX_DECIMAL_DIGITS,
        decimal_places=globals.MAX_DECIMAL_PLACES,
        source='geometry.location.lat'
    )
    longitude = serializers.DecimalField(
        max_digits=globals.MAX_DECIMAL_DIGITS,
        decimal_places=globals.MAX_DECIMAL_PLACES,
        source='geometry.location.lng'
    )

    class Meta:
        model = models.Location
        fields = ['id', 'addr_address', 'business_status', 'formatted_address', 'formatted_phone_number', 'icon', 'icon_background_color', 'icon_mask_base_uri',
                        'international_phone_number', 'name', 'place_id', 'rating', 'reference', 'url', 'user_ratings_total', 'vicinity', 'website',
                        'compound_code', 'global_code', 'latitude', 'longitude']
        read_only_fields = ['id']

说明

  • 序列化器会自动从传入数据的geometry.location.lat和geometry.location.lng路径取值,直接映射到模型的latitude和longitude字段。
  • 如果需要在序列化输出时保留geometry.location的嵌套结构,可以结合SerializerMethodField自定义输出格式,但如果只是完成数据到单个模型的映射,上述方法最简洁高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 08:50:35