【问题标题】:Django rest framework nested serialization not working properlyDjango rest框架嵌套序列化无法正常工作
【发布时间】:2016-07-15 04:20:13
【问题描述】:

我的应用中有这些序列化程序:

class ScheduleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Schedule
        fields = ('id',)

class DisciplineSerializer(serializers.ModelSerializer):
    class Meta:
        model = Discipline
        fields = ('id',)


class WriteTeacherSerializer(serializers.ModelSerializer):
    disciplines = DisciplineSerializer(many=True)
    schedules = ScheduleSerializer(many=True)
    class Meta:
        model = Teacher
        fields = ('phone_number', 'bio', 'price', 'disciplines', 'schedules')
        depth = 1

    def update(self, instance, validated_data):

        print "\n"
        #Debugging here
        print validated_data
        print "\n"
        print instance.__dict__
        print "\n"

        instance.phone_number = validated_data['phone_number']
        instance.bio = validated_data['bio']
        instance.price = validated_data['price']
        disciplines = validated_data.pop('disciplines')
        schedules = validated_data.pop('schedules')
        for discipline in disciplines:
            try:
                stored_discipline = Discipline.objects.get(id=discipline['id'])
                instance.disciplines.add(stored_discipline)
            except Discipline.DoesNotExist:
                raise Http404

        for schedule in schedules:
            try:
                stored_schedule = Schedule.objects.get(id=schedule['id'])
                instance.schedules.add(stored_discipline)
            except Discipline.DoesNotExist:
                raise Http404
        instance.save()
        return instance

如您所见,我正在尝试使用字段schedulesdisciplines 进行嵌套序列化。我想我遵循了文档,但是当我测试它时嵌套序列化不起作用。我打印了instancevalidated_data 对象并在shell 上进行了测试。

我以这种格式开始数据:

data = {u'phone_number': u'+99999999999', u'bio': u'BIO', u'price': 40, u'disciplines': [{'id': 1}], u'schedules': [{'id': 2}]}

我得到一个教师实例并像这样启动序列化程序:

serializer = WriteTeacherSerializer(teacher, data=data)

它在serializer.is_valid() 调用中显示为 True。

但是,当我尝试保存它时,validated_datainstance.__dict__ 是这样的:

#validated_data
{u'phone_number': u'+5584998727770', u'bio': u'BIO', u'price': 40, u'disciplines': [OrderedDict()], u'schedules': [OrderedDict()]}


#instance.__dict__
{'phone_number': u'', 'bio': u'', 'price': 50, 'profile_id': 2, '_state': <django.db.models.base.ModelState object at 0xb64a6bec>, 'id': 6}

他们似乎没有注意到嵌套字段使update() 方法不起作用。

我做错了吗?

这也是我的教师模型:

class Teacher(models.Model):

    price = models.IntegerField(default=50)
    phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Wrong phone number format.")
    phone_number = models.CharField(validators=[phone_regex], max_length=15, blank=True)
    profile = models.OneToOneField(Profile, on_delete=models.CASCADE)
    schedules = models.ManyToManyField(Schedule, related_name='schedules')
    disciplines = models.ManyToManyField(Discipline, related_name='disciplines')
    bio = models.CharField(max_length=200, blank=True)

【问题讨论】:

    标签: python django debugging serialization django-rest-framework


    【解决方案1】:

    如果你只是发送IDs那么你不需要添加嵌套序列化器,只需指定ForeignKeyManyToManyField的字段名称。

    class WriteTeacherSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = Teacher
            fields = ('phone_number', 'bio', 'price', 'disciplines', 'schedules')
    

    我也想知道是不是因为你有一个depth=1 标志?

    DRF 不支持开箱即用的嵌套更新。您必须重写序列化程序的更新方法,并编写您自己的更新逻辑,因此如果您发送嵌套数据,您会看到此警告的错误。

    【讨论】:

    • 出于某种原因,我必须指定这些字段才能使序列化程序工作。问题是我认为我的观点是以某种方式将学科和时间表对象转变为字符串。我只是在启动序列化程序之前再次将它们转换回对象,它现在正在工作。
    • Joab 你能解释一下或者贴一个代码sn-p吗?我也有同样的问题
    • @JesusAlmaral 的问题是,如果您希望将相关对象序列化为对象而不是原始值,那么您需要使用嵌套序列化程序对其进行序列化:django-rest-framework.org/api-guide/serializers/…
    猜你喜欢
    • 2021-06-23
    • 2018-12-13
    • 2020-08-05
    • 2020-07-07
    • 2016-08-01
    • 2014-07-26
    • 2019-12-23
    • 2016-05-14
    • 2017-08-07
    相关资源
    最近更新 更多