首页 文章

Django Rest Framework - 嵌套序列化无法按预期工作

提问于
浏览
9

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

我能正确地序列化整个 Address 模型,但是我只需要 Address 中的几个字段,嵌套在我的序列化 Outlet 中 . 有一个

尝试在序列化程序OutletSerializer上获取字段outlet_address的值时出现AttributeError . 序列化程序字段可能名称不正确,并且与Outlet实例上的任何属性或键都不匹配 . 原始异常文本是:'Outlet'对象没有属性'outlet_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

api_v1/serializers.py

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属性,而我预计它应该能够在序列化程序中 .

尝试在序列化程序OutletSerializer上获取字段outlet_address的值时出现AttributeError . 序列化程序字段可能名称不正确,并且与Outlet实例上的任何属性或键都不匹配 . 原始异常文本是:'Outlet'对象没有属性'outlet_address' .

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

  • many= 添加到ModelSerializer

  • related_name= 添加到所有模型

3 回答

  • 10

    试试这个:

    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_address”的属性,它有一个名为“address”的属性 .

    请参阅此处查找类似问题:Django Rest framework keeps returning error on nested relationship

  • 3

    除了其他答案,我想添加以下内容以防有人在这里登陆 .

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

    如果我们需要reverse relation,那么显然模型字段中不会有这样的字段 .

    例如,对于问题中的特定模型,如果我们需要引用地址序列化器中的所有插座,就会发生这种情况 .

    因此我们需要:(a)为另一个模型的外键指定 related_name . 这是我们使用 outlet_address 的地方,因为这是插座模型中地址字段的相关名称 .

    或者(b)如果没有相关名称则使用默认的Django名称,将 _set 追加到模型名称(例如 outlet_set .

  • 8

    Model Outlet有一个“地址”字段,而不是outlet_address . 我建议像这样设置你的序列化器:

    class OutletSerializer(serializers.ModelSerializer):
        address = AddressSerializer(many=False)
    
        class Meta:
            model = Outlet
            fields = ('id', 'name', 'thumbnail', 'address')
            depth = 2
    

相关问题