Python - 无法修改 Django Rest Framework 中的 serializer.data 字典

标签 python dictionary django-rest-framework

我尝试添加一个键 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/

相关文章:

python - 在哪里可以找到 Python3 中的 WidgetRedirector?

Python 在循环中从 Csv 创建 XML

python - 模型 django 中唯一随机默认值的迁移问题

python - 使用 tkinter、GUI 制作字典

运行有限或无限生成器函数时出现 Python3 错误

python - 临时解压字典

python - 迭代嵌套字典列表

python - Rest框架序列化器只读

python - 在 Django-rest-framework 中创建具有关系的模型

django 属性错误 : dict object has no attribute 'pk'