我尝试添加一个键 serializer.data['test'] = 'asdf'
,这似乎没有做任何事情。
我想转换键值的表示。为此,我尝试使用该值计算新值并替换字典中的旧值。
这就是我想要完成的,但我不知道为什么这个值没有被替换。没有抛出任何错误,生成的字典也没有证据表明我试图替换任何东西:
class PlaceDetail(APIView):
def get(self, request, pk, format=None):
place = Place.objects.select_related().get(pk=pk)
serializer = PlaceSerializer(place)
#serializer.data['tags'] = pivot_tags(serializer.data['tags'])
serializer.data['test'] = 'asdf'
print(serializer.data['test'])
return Response(serializer.data)
终端:KeyError:'test'
我通过打印观察到 serializer.data
是一个字典。
我还测试了我尝试使用的语法应该有效:
>>> test = {'a': 'Alpha'}
>>> test
{'a': 'Alpha'}
>>> test['a']
'Alpha'
>>> test['a'] = 'asdf'
>>> test
{'a': 'asdf'}
如何正确修改 serializer.data
字典?
最佳答案
Serializer.data
属性返回一个 OrderedDict
,它是使用 serializer._data
构造的。返回值不是 serializer._data
本身。
因此改变serializer.data
的返回值不会改变serializer._data
成员。因此,以下对 serializer.data
的调用没有改变。
# In class Serializer(BaseSerializer)
@property
def data(self):
ret = super(Serializer, self).data
return ReturnDict(ret, serializer=self)
# In class ReturnDict(OrderedDict)
def __init__(self, *args, **kwargs):
self.serializer = kwargs.pop('serializer')
super(ReturnDict, self).__init__(*args, **kwargs)
您可以保留一份 serializer.data
的返回值副本,这是一个有序的字典,并根据需要对其进行操作。
例子:
# keep the return value of serializer.data
serialized_data = serializer.data
# Manipulate it as you wish
serialized_data['test'] = 'I am cute'
# Return the manipulated dict
return Response(serialized_data)
为什么:
如果你查看 Django Restframework 的源代码,你会在 Serializer
类中看到,
Serializer._data
只是一个普通的字典。Serializer.data
是一种装饰成属性的方法。它返回一个ReturnDict
对象,该对象是从OrderedDict
派生的自定义类。返回的ReturnDict
对象使用Serializer._data
中的键/值对进行初始化。
如果 Serializer.data
直接返回 Serializer._data
,那么您的原始方法将按预期工作。但它不会工作,因为它返回另一个使用 Serializer._data
构造的类似字典的对象。
请记住,Serializer.data
的返回值不是Serializer._data
,而是一个有序的类似字典的对象。操作返回值不会更改 Serializer._data
。
我相信 serializer.data
不直接返回 serializer._data
的原因是为了避免意外更改数据并返回 的漂亮表示serializer._data
.
关于Python - 无法修改 Django Rest Framework 中的 serializer.data 字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35422686/