不可散列的类型:"OrderedDict" [英] unhashable type: 'OrderedDict'

查看:69
本文介绍了不可散列的类型:"OrderedDict"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试在Postman中进行PUT请求时,我在Django中遇到了一个问题.

I am encountering an issue in Django when I try to do a PUT request in Postman.

我怀疑问题是因为我在模型类中嵌套了序列化器,但我不确定.

I suspect the issue is because I have nested serializers in my model class, but I am not sure.

class Foo(models.Model):
    foo_name = models.CharField(max_length=50, unique=True)

    foo_statistics = models.ManyToManyField(TrainStatistics)

class FooSerializer(serializers.ModelSerializer):
    blah_statistics = BlahStatisticsSerializer(many=True)

    class Meta:
        model = Foo
        fields = ('foo_statistics')
        depth = 2 

    def create(self, validated_data):
        """
        Create and return a new `Summary` instance, given the validated data.
        """

        blah_statistics_data = validated_data.pop('blah_statistics')
        foo = Foo(**validated_data)

        for blah_statistic in blah_statistics_data:
            FooStatistic.objects.create(summary=summary, **train_statistic)
        return summary

    def update(self, instance, validated_data):
        """
        Update and return an existing `Foo` instance, given the validated data.
        """
        instance.blah_statistics = validated_data.get('blah_statistics', instance.blah_statistics) # This line is causing problems

您知道什么可能导致此问题吗?

Any idea what could be causing this issue?

推荐答案

问题是,经过验证的数据会将 train_statistics 转换为 OrderedDict (总是有些棘手的工作)(带有嵌套的序列化程序),因此 OrderedDicts 无法散列,因此当您尝试" .get "时,会引发错误.

The problem is that the validated data turns train_statistics into a OrderedDict(always it's a bit tricky working with nested serializers), so OrderedDicts are unhashable, so when you try to ".get" it raises an error.

一个选项是将您的字段 train_statistics 设置为只读.

An option is to set your field train_statistics into read only.

然后在您的 update()方法中,而不是使用 validated_data 来获取 train_statistics ,请使用 request.data 获取它们.对 create()方法执行相同的操作.

Then in your update() method, instead of using validated_data to get train_statistics, use request.data for getting them. Do the same for create() method.

class SummarySerializer(serializers.ModelSerializer):
    train_statistics = TrainStatisticsSerializer(many=True, read_only=True)

    class Meta:
        model = Summary
        fields = ('train_statistics')
        depth = 2 

    def create(self, validated_data):
        """
        Create and return a new `Summary` instance, given the validated data.
        """
        request = self.context['request']
        train_statistics_data = request.data.get('train_statistics')
        summary = Summary.objects.create(**validated_data)

        for train_statistic in train_statistics_data:
            TrainStatistics.objects.create(summary=summary, **train_statistic)
        return summary

    def update(self, instance, validated_data):
        """
        Update and return an existing `Summary` instance, given the validated data.
        """
        request = self.context['request']
        instance.train_statistics =request.data.get('train_statistics', instance.train_statistics) # This line is causing problems

调用序列化程序时,需要将请求对象作为上下文数据传递.

When you call your serializer, you need to pass request object as context data.

SummarySerializer(instance, data=data, context={'request':request})

SummarySerializer(data=data, context={'request':request})

这篇关于不可散列的类型:"OrderedDict"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆