首页 文章

在Django Rest Framework中保存实例嵌套的序列化程序

提问于
浏览
0

我在Django Rest Framework中保存实例 Live_In 嵌套序列化程序时遇到问题 . 希望你的伙伴帮助我!我认为这只是一个基本问题 .

My Serializers:

我认为在编写保存实例时会出错

class CityLiveInSerializer(ModelSerializer):
    country = CharField(required=False, source='country.name')
    class Meta:
        model = City
        fields = [
            'name',
            'slug',
            'country'
        ]    

class UserEditSerializer(ModelSerializer):
    live_in = CityLiveInSerializer(source='profile.live_in')
    about = serializers.CharField(source='profile.about')
    class Meta:
        model = User
        fields = [
            'username',
            'live_in',
            'about',
        ]

    def update(self, instance, validated_data):
        instance.username = validated_data.get('username', instance.username)
        instance.save()
        # Update Serializers Profile
        if (validated_data.get('profile') is not None):
            profile_data = validated_data.pop('profile')
            profile = instance.profile
            profile.about = profile_data.get('about', profile.about)
            profile.save()

        if (validated_data.get('live_in') is not None):
          live_in_data = validated_data.pop('live_in')
          try:
              city = City.objects.get(name=live_in_data['name'])
          except City.DoesNotExist:   
              city = City.objects.create(**live_in_data)
          instance.profile.live_in = city
          instance.profile.save()
        return instance

My City Model (Live_in)

class City(BaseCity):
    class Meta(BaseCity.Meta):
        swappable = swapper.swappable_setting('cities', 'City')

class BaseCity(Place, SlugModel):
    name = models.CharField(max_length=200, db_index=True, verbose_name="standard name")
    country = models.ForeignKey(swapper.get_model_name('cities', 'Country'), related_name='cities', null=True, blank=True)

My Profile Model

class Profile(models.Model):
    # Extend User
    user = models.OneToOneField(User, unique=True)
    about = models.TextField(max_length=1000, default='', blank=True, null=True)
    live_in = models.ForeignKey(City, null=True, blank=True, related_name="live_in")

Postman(Json)发送的数据

{ "live_in": { "name": "Encamp" } }

TraceError:

文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/rest_framework/serializers.py”在数据263中.self._data = self.to_representation(self.instance)

文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/rest_framework/serializers.py”in_representation 488. attribute = field.get_attribute(instance)

在get_attribute中文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/rest_framework/fields.py”463. raise type(exc)(msg)

异常类型:/ api / v1 / users / account / edit / Exception值中的AttributeError:尝试在序列化程序 UserEditSerializer 上获取字段 live_in 的值时获得AttributeError . 序列化程序字段可能名称不正确,并且与 User 实例上的任何属性或键都不匹配 . 原始异常文本是:'User'对象没有属性'live_in' .

1 回答

  • 1

    首先,在这种情况下你不需要 many=True . 它需要相关对象列表,但您只能传递一个城市 . 其次 live_in 是配置文件模型的属性,因此您需要更新配置文件并添加源参数:

    live_in = CityLiveInSerializer(source="profile.live_in")
    
    def update(self, instance, validated_data):
        instance.username = validated_data.get('username', instance.username)
        instance.save()
        # Update Serializers Profile
        if (validated_data.get('profile') is not None):
            profile_data = validated_data.pop('profile')
            profile = instance.profile
            profile.about = profile_data.get('about', profile.about)
            if (profile_data.get('live_in') is not None):
                live_in_data = profile_data.pop('live_in')
                try:
                    city = City.objects.get(name=live_in_data["name"])
                except City.DoesNotExist:   
                    city = City.objects.create(**live_in_data)
            profile.live_in = city 
            profile.save()
    
        return instance
    

    在这种情况下,您需要允许创建没有国家/地区的城市,因此您需要将null = True,blank = True添加到国家/地区属性:

    class BaseCity(Place, SlugModel):
        name = models.CharField(max_length=200, db_index=True, verbose_name="standard name")
        country = models.ForeignKey(swapper.get_model_name('cities', 'Country'),
                                related_name='cities', null=True, blank=True)
    

相关问题