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

DRF嵌套序列化many=True返回数组而非对象的问题求助

问题:DRF嵌套序列化器返回地址为数组而非单个对象

我使用嵌套序列化器获取每个设施的地址信息,仅当给LeadFacilityDetailFacilitySerializer添加many=True参数时,地址值才会显示,但此时地址对象会被包裹在数组[]中,导致前端访问{info.LeadFacilityDetailFacility.AddressInfo.City}时返回undefined。

相关代码

serializers.py

class LeadAddressSerializer(serializers.ModelSerializer):
    class Meta:
        model = FacilityAddress
        fields = (
            "PrimaryAddress",
            "SecondaryAddress",
            "City",
            "RegionOrState",
            "PostalCode",
        )

class LeadFacilityDetailFacilitySerializer(serializers.ModelSerializer):
    AddressInfo = LeadAddressSerializer(source="fa", many=True)
    class Meta:
        model = Facility
        fields = ('mainimage', 'Name', 'AdministratorCell', 'AddressInfo')


class LeadFacilityDetailSerializer(serializers.ModelSerializer):
    LeadFacilityDetailFacility = LeadFacilityDetailFacilitySerializer(source="assigned_facilities")    

    class Meta:
        model = LeadFacilityAssign
        fields = ('assigned_facilities', 'datetime', 'id', 'LeadFacilityDetailFacility')

models.py

class FacilityAddress(models.Model):
    PrimaryAddress = models.CharField(max_length=150, null=True, blank=True)
    SecondaryAddress = models.CharField(max_length=150, null=True, blank=True)
    City = models.CharField(max_length=150, null=True, blank=True)
    RegionOrState = models.CharField(max_length=50, null=True, blank=True)
    PostalCode = models.CharField(max_length=30, null=True, blank=True)
    Geolocation = models.CharField(max_length=30, null=True, blank=True)
    AddressInfo = models.ForeignKey(Facility, null=True, blank=True, on_delete=models.CASCADE, related_name='fa')

class Facility(models.Model):
    Name = models.CharField(max_length=150, null=True, blank=False)

尝试过的方法及问题

我试过用to_representation方法处理数组,但返回的地址对象会带上ID,形成带键的结构,不符合需求:

def to_representation(self, instance):
    representation = super().to_representation(instance)
    representation['AddressInfo'] = {FacilityAddress["id"]: FacilityAddress for FacilityAddress in representation['AddressInfo']}
    return representation

解决方法

方法1:修改模型为一对一关系(推荐,符合业务逻辑)

如果业务上一个设施对应唯一地址,将FacilityAddress中的外键改为一对一字段:

class FacilityAddress(models.Model):
    # ... 保留原有字段
    AddressInfo = models.OneToOneField(Facility, null=True, blank=True, on_delete=models.CASCADE, related_name='fa')

然后修改序列化器,去掉many=True参数:

class LeadFacilityDetailFacilitySerializer(serializers.ModelSerializer):
    AddressInfo = LeadAddressSerializer(source="fa")  # 移除many=True
    class Meta:
        model = Facility
        fields = ('mainimage', 'Name', 'AdministratorCell', 'AddressInfo')

方法2:在序列化器中提取第一个地址对象

如果业务允许一个设施有多个地址,但前端仅需第一个,修改序列化器的to_representation方法:

class LeadFacilityDetailFacilitySerializer(serializers.ModelSerializer):
    AddressInfo = LeadAddressSerializer(source="fa", many=True)
    class Meta:
        model = Facility
        fields = ('mainimage', 'Name', 'AdministratorCell', 'AddressInfo')

    def to_representation(self, instance):
        representation = super().to_representation(instance)
        # 提取第一个地址,无地址时返回空对象或None
        if representation.get('AddressInfo'):
            representation['AddressInfo'] = representation['AddressInfo'][0]
        else:
            representation['AddressInfo'] = {}  # 可根据需求改为None
        return representation

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 17:25:15