【问题标题】:Django Rest Framework update nested serializerDjango Rest Framework 更新嵌套序列化程序
【发布时间】:2016-02-09 08:45:57
【问题描述】:

我对 DRF 嵌套序列化程序有很大的误解。我阅读了有关此的文档,发现我需要提供自己的更新方法。所以,这里是:

class SkillsSerializer(serializers.ModelSerializer):

class Meta:
    model = Skills

class ProfileSerializer(serializers.ModelSerializer):
    skills = SkillsSerializer(many=True)

    class Meta:
        model = Profile
        fields = ('user', 'f_name', 'l_name', 'bd_day', 'bd_month', 'bd_year', 'spec', 'company', 'rate', 'skills', 'bill_rate', 'website', 'about', 'city', 'avatar', 'filled')

    def update(self, instance, validated_data):
        instance.user_id = validated_data.get('user', instance.user_id)
        instance.f_name = validated_data.get('f_name', instance.f_name)
        instance.l_name = validated_data.get('l_name', instance.l_name)
        instance.bd_day = validated_data.get('bd_day', instance.bd_day)
        instance.bd_month = validated_data.get('bd_month', instance.bd_month)
        instance.bd_year = validated_data.get('bd_year', instance.bd_year)
        instance.spec = validated_data.get('spec', instance.spec)
        instance.company = validated_data.get('company', instance.company)
        instance.rate = validated_data.get('rate', instance.rate)
        instance.website = validated_data.get('website', instance.website)
        instance.avatar = validated_data.get('avatar', instance.avatar)
        instance.about = validated_data.get('about', instance.about)
        instance.city = validated_data.get('city', instance.city)
        instance.filled = validated_data.get('filled', instance.filled)
        instance.skills = validated_data.get('skills', instance.skills)
        instance.save()
        return instance

我将它与文档进行了比较,没有发现任何差异。但是在这种情况下,当我尝试更新技能时,它不起作用。还有一个真正的魔力:当我把它放上去的时候

instance.skills = validated_data.get('bd_day', instance.skills)

效果非常好!例如,如果我设置 bd_day = 12,则更新方法会使用 ID 为 1 和 2 的技能保存实例。 因此,似乎序列化程序忽略了 AJAX 数据中的技能,并且仍在思考,技能序列化程序是只读的。 那么,这个逻辑的意义何在?我如何才能最终更新我的技能?

更新

我的模型:

class Skills(models.Model):
    tags = models.CharField(max_length='255', blank=True, null=True)

    def __unicode__(self):
        return self.tags


class Profile(models.Model):
     user = models.OneToOneField(User, primary_key=True)
     ...
     skills = models.ManyToManyField(Skills, related_name='skills')
     ...

更新2

对于这种情况仍然没有任何解决方案!我尝试了thisthis - 结果相同。 序列化程序似乎完全忽略了 JSON 数据。

【问题讨论】:

  • 模型Skills有哪些字段,每个字段的数据类型是什么?
  • @ArpitGoyal - 我更新了我的问题。
  • 您要向 API 点发送什么数据?
  • @Linovia 实际上我尝试了几种方法,但最后我只发送了一个带有技能 ID 的字符串。像这样:123,其中 id1=1,id2=2 等等。

标签: django serialization django-rest-framework


【解决方案1】:

您在提供非模型数据时遇到了问题。

这个:

    instance.skills = validated_data.get('skills', instance.skills)

不会提供技能模型实例,而是提供字典。 您需要先获取技能实例,然后将它们注入到 instance.skills。

【讨论】:

  • 你能举个例子吗?
  • 是的,但是我没有找到不通过表的多对多更新方法的示例。
  • 那是因为用例太多了。当某些数据发生变化时,您更愿意更新还是创建新的相关实例?搬家政策怎么样?等等
  • 我仍然没有针对这种情况的任何解决方案。我尝试使用此建议link,但没有帮助。如果我无法从 JSON 接收到 Skills() 实例,我无法理解如何获取它?
【解决方案2】:

我不得不更新答案,你这样做效率低下,所以看看解决方案,它要好得多

class ProfileSerializer(serializers.ModelSerializer):

    class Meta:
        model = Profile
        fields = ('user', 'f_name', ... 'skills', ... 'filled')
        depth = 1

class ProfileUpdateSerializer(serializers.ModelSerializer):
    skills = serializers.PrimaryKeyRelatedField(many=True, queryset=Skills.objects.all(), required=False)

    class Meta:
        model = Profile
        fields = ('user', 'f_name', ... 'skills', ... 'filled')
    
    def update(self, instance, validated_data):
        user = validated_data.pop('user', {})
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()

        if user:
            User.objects.filter(id=self.context['request'].user.id).update(**user)


        return instance

但在那之后我遇到了另一个问题。我只能从一系列技能中获得一个元素。我在这里找到了解决方案:

 $.ajax({
    url: myurl,
    type: 'PUT',
    dataType: 'json',
    traditional: true,<-----THIS!
    data: data,

就是这样!它就像一个魅力!

希望我的解决方案有用!

【讨论】:

  • 我遇到了同样的问题,但我不认为根据 DRY 创建两个序列化程序是理想的。有什么新想法吗?
猜你喜欢
  • 2017-01-28
  • 1970-01-01
  • 2018-10-26
  • 1970-01-01
  • 1970-01-01
  • 2017-12-03
  • 2019-08-10
  • 2023-03-26
  • 2018-07-06
相关资源
最近更新 更多