Python Django Rest Framework-嵌套序列化未按预期工作

Python Django Rest Framework-嵌套序列化未按预期工作,python,django,serialization,django-rest-framework,Python,Django,Serialization,Django Rest Framework,使用Django REST框架时,我无法在嵌套的序列化对象中显示选定字段 我能够正确地序列化整个地址模型,但我只希望地址中的几个字段嵌套在序列化的出口中。有一个 试图获取序列化程序OutletSerializer上的字段outlet\u address的值时,获取了AttributeError。 序列化程序字段的名称可能不正确,并且与Outlet实例上的任何属性或键都不匹配。 原始异常文本为:“Outlet”对象没有属性“Outlet\u address” api_v1/models.py cl

使用Django REST框架时,我无法在嵌套的序列化对象中显示选定字段

我能够正确地序列化整个
地址
模型,但我只希望
地址
中的几个字段嵌套在序列化的
出口
中。有一个

试图获取序列化程序
OutletSerializer
上的字段
outlet\u address
的值时,获取了AttributeError。 序列化程序字段的名称可能不正确,并且与
Outlet
实例上的任何属性或键都不匹配。 原始异常文本为:“Outlet”对象没有属性“Outlet\u address”

api_v1/models.py

class Address(models.Model):
    building = models.CharField(_("shop number, floor & building"), max_length=128)
    street = models.CharField(_("street"), max_length=128, blank=True)
    area = models.ManyToManyField(Area, related_name='address')
    city = models.ForeignKey(City, related_name='address')
    pin_code = models.CharField(_("PIN code"), max_length=6, default="")

    def __unicode__(self):
        return self.building + " " + self.street + " ..."


class Outlet(models.Model):
    name = models.CharField(max_length=100, blank=True)
    chain = models.ForeignKey(Chain, related_name='outlet', blank=True, null=True)
    organization = models.ForeignKey(Organization, blank=True, null=True)
    address = models.OneToOneField(Address, related_name='outlet_address')
    thumbnail = AjaxImageField(upload_to='thumbnails',
                               max_height=200,  #optional
                               max_width=200,  # optional
                               crop=True)  # optional
    date_created = models.DateTimeField(_('date created'), default=timezone.now)

    def __unicode__(self):
        return self.name
from rest_framework import serializers
from api_v1.models import Outlet, Address

class AddressSerializer(serializers.ModelSerializer):
    #address_area = AreaSerializer(many=False)

    class Meta:
        model = Address
        fields = ('building', 'street',)
        depth = 3


class OutletSerializer(serializers.ModelSerializer):
    outlet_address = AddressSerializer(many=False)
    #area = serializers.CharField(source='address.area') #multiple levels of nesting?

    class Meta:
        model = Outlet
        fields = ('id', 'name', 'thumbnail', 'outlet_address')
        # fields = ('id', 'name', 'thumbnail', 'address') # this works
        depth = 3
api_v1/serializers.py

class Address(models.Model):
    building = models.CharField(_("shop number, floor & building"), max_length=128)
    street = models.CharField(_("street"), max_length=128, blank=True)
    area = models.ManyToManyField(Area, related_name='address')
    city = models.ForeignKey(City, related_name='address')
    pin_code = models.CharField(_("PIN code"), max_length=6, default="")

    def __unicode__(self):
        return self.building + " " + self.street + " ..."


class Outlet(models.Model):
    name = models.CharField(max_length=100, blank=True)
    chain = models.ForeignKey(Chain, related_name='outlet', blank=True, null=True)
    organization = models.ForeignKey(Organization, blank=True, null=True)
    address = models.OneToOneField(Address, related_name='outlet_address')
    thumbnail = AjaxImageField(upload_to='thumbnails',
                               max_height=200,  #optional
                               max_width=200,  # optional
                               crop=True)  # optional
    date_created = models.DateTimeField(_('date created'), default=timezone.now)

    def __unicode__(self):
        return self.name
from rest_framework import serializers
from api_v1.models import Outlet, Address

class AddressSerializer(serializers.ModelSerializer):
    #address_area = AreaSerializer(many=False)

    class Meta:
        model = Address
        fields = ('building', 'street',)
        depth = 3


class OutletSerializer(serializers.ModelSerializer):
    outlet_address = AddressSerializer(many=False)
    #area = serializers.CharField(source='address.area') #multiple levels of nesting?

    class Meta:
        model = Outlet
        fields = ('id', 'name', 'thumbnail', 'outlet_address')
        # fields = ('id', 'name', 'thumbnail', 'address') # this works
        depth = 3
此时,它无法在outlet模型中找到outlet_address属性,而我希望它能够在序列化程序中找到

尝试获取字段的值时获取AttributeError 序列化程序上的
OutletSerializer\u地址
。序列化程序 字段的名称可能不正确,并且与上的任何属性或键都不匹配
出口
实例。原始异常文本为:“Outlet”对象 没有“出口地址”属性

如其他答案所述,我尝试过:

  • many=
    添加到ModelSerializer
  • 相关的\u name=
    添加到所有模型
  • 型号插座有一个“地址”字段,而不是插座地址。我建议您将序列化程序设置为:

    类OutletSerializer(serializers.ModelSerializer):
    address=AddressSerializer(many=False)
    类元:
    型号=出口
    字段=('id','name','缩略图','address')
    深度=2
    
    试试这个:

    from rest_framework import serializers
    from api_v1.models import Outlet, Address
    
    class AddressSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = Address
            fields = ('building', 'street',)
            depth = 3
    
    
    class OutletSerializer(serializers.ModelSerializer):
        address = AddressSerializer(many=False) # make it address, not outlet_address
    
        class Meta:
            model = Outlet
            fields = ('id', 'name', 'thumbnail', 'address') # make this address as well, not outlet_address
            depth = 3
    
    我之所以要进行上述更改,是因为Outlet模型没有一个名为“Outlet\u address”的属性,它有一个名为“address”的属性


    参见此处了解类似问题:

    除其他答案外,我还想添加以下内容,以防有人也登陆此处

    嵌套序列化要求字段名位于模型字段中才能工作

    如果我们需要一个,那么显然在模型字段中没有这样的字段

    例如,对于问题中的特定模型,如果需要引用地址序列化程序中的所有出口,就会发生这种情况

    因此,我们需要:(a)指定与另一个模型的外键相关的
    名称。这是我们将使用
    outlet\u address
    ,因为这是outlet模型中地址字段的相关名称


    或者(b)如果没有相关的名称,则使用默认的Django名称,在模型名称后面附加
    \u set
    (例如
    outlet\u set

    我之前确实看到了链接的文章,但它是用于反向关系的。您的答案非常有效,而且现在我对DRF魔术也有了更好的理解。谢谢@Wtower!非常有用。我向您表示感谢。