[英]'collections.OrderedDict' object has no attribute 'pk' - django rest framework
I have a model and I want to write an update()
method for it in order to update.我有一个模型,我想为它编写一个
update()
方法以进行更新。 The below snippet is my model:下面的代码片段是我的模型:
class Klass(models.Model):
title = models.CharField(max_length=50)
description = models.CharField(max_length=500)
university = models.CharField(max_length=50,blank=True, null=True)
teacher = models.ForeignKey(Profile, related_name='teacher', on_delete=models.CASCADE)
and the below snippet is corresponding Serializer
:下面的代码片段是相应的
Serializer
:
class KlassSerializer(ModelSerializer):
teacher = ProfileSerializer()
url = HyperlinkedIdentityField(view_name='mainp-api:detail', lookup_field='pk')
klass_settings = KlassSettingsSerializer()
class Meta:
model = Klass
fields = ('url', 'id', 'title', 'description', 'university','teacher')
def update(self, instance, validated_data):
instance.title = validated_data.get('title', instance.title)
instance.description = validated_data.get('description', instance.description)
instance.university = validated_data.get('university', instance.university)
instance.save()
return instance
And for update, I use below snippet:对于更新,我使用以下代码段:
class KlassAPIView(APIView):
def put(self, request, pk=None):
if pk == None:
return Response({'message': 'You must specify class ID'}, status=HTTP_400_BAD_REQUEST)
klass = Klass.objects.get(pk=pk)
if request.user.profile.type != 't':
raise PermissionDenied(detail={'message': 'You aren't teacher of this class, so you can't edit information.'})
serializer = KlassSerializer(data=request.data, context={'request': request})
serializer.initial_data['teacher'] = request.user.profile.__dict__
if serializer.is_valid():
serializer.update(instance=klass, validated_data=serializer.data) # Retrieve teacher and store
return Response({'data': serializer.data}, status=HTTP_200_OK)
else:
return Response({'data': serializer.errors}, status=HTTP_400_BAD_REQUEST)
but when I send data with PUT
method, it returns below error:但是当我使用
PUT
方法发送数据时,它返回以下错误:
AttributeError at /api/class/49/
/api/class/49/ 处的属性错误
'collections.OrderedDict' object has no attribute 'pk'
'collections.OrderedDict' 对象没有属性 'pk'
and the error occurs in serializer.update(instance=klass, validated_data=serializer.data)
line.并且错误发生在
serializer.update(instance=klass, validated_data=serializer.data)
行中。
Just ran into the same error.刚刚遇到了同样的错误。
In my case the problem was I accessed serializer.data
before doing serializer.save()
.就我而言,问题是我在执行
serializer.save()
之前访问了serializer.data
。
Google dropped me here, so maybe someone else will also find this helpful.谷歌把我放在这里,所以也许其他人也会觉得这很有帮助。
Source: https://github.com/encode/django-rest-framework/issues/2964来源: https : //github.com/encode/django-rest-framework/issues/2964
i don't know if this helps.我不知道这是否有帮助。 I always add the
id
field in the serializer due to that similar issue:由于类似的问题,我总是在序列化程序中添加
id
字段:
id = serializers.ModelField(model_field=YourModel._meta.get_field('id'), required=False)
Make sure it's required=False
because when you create a new record the id
field is not present.确保它是
required=False
因为当您创建新记录时id
字段不存在。
Well in my case, I was doing:好吧,就我而言,我正在做:
champions_list = []
for champion in champions_serializer.data:
c = {"id": champion.id}
champions_list.append(c)
And the correct way to do it is:正确的做法是:
champions_list = []
for champion in champions_serializer.data:
c = {"id": champion["id"]}
champions_list.append(c)
And make sure that you return the id inside the serializer.并确保您在序列化程序中返回 id。
Many answers to this question note that serializer.save()
must be called before using serializer.data
.这个问题的许多答案都指出在使用
serializer.data
之前必须调用serializer.save()
。
In my case, I was definitely calling serializer.save()
, however, I was overriding the save
method on my serializer and did not set self.instance
on the serializer in that method.就我而言,我肯定是在调用
serializer.save()
,但是,我覆盖了序列化程序上的save
方法,并且没有在该方法中的序列化self.instance
上设置self.instance
。
So if you are overriding save
be sure to do:因此,如果您要覆盖
save
,请务必执行以下操作:
class MySerializer(serializers.ModelSerializer):
def save(self, *args, **kwargs):
...
self.instance = instance
return self.instance
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.