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
相关产品推荐
相关产品推荐

