覆盖Django REST Framework中的serializer.data

use*_*731 8 python django rest

我一直试图改变Django REST Framework管理面板的表单字段的价值,并且出于某种原因,改变永远不会发生.我有下面的序列化器

class SomeView(ModelViewSet):
  queryset = MyModel.objects.all()
  serializer_class = MyModelSerializer

  # I Want to override this and change the POST data
  def perform_create(self, serializer):
     user = self.request.user.id

     # this was a form field where I manually entered the user ID
     # I now want it to default to the logged in user
     serializer.data['user'] = user

     # This returns the original user that was entered into the form field
     print serializer.data
Run Code Online (Sandbox Code Playgroud)

我检查了serializer.data,dir()它只是一个python字典,所以我无法弄清楚为什么我无法修改该值.作为测试,我尝试添加额外的值,但这也不起作用

# this doesnt work
serializer.data['some_new_field'] = 'test'
Run Code Online (Sandbox Code Playgroud)

编辑

另外,我可以复制数据并进行编辑

fake_data = serializer.data.copy()
fake_data['old_value'] = 'new value'
Run Code Online (Sandbox Code Playgroud)

但是,它始终无法验证

serializer = MyModelSerializer(data=fake_data)
serializer.is_valid() # returns false
Run Code Online (Sandbox Code Playgroud)

编辑编辑:

好的,因此验证错误是由Django返回SimpleLazyObject引起的.当我执行数据副本时,现在一切正常,但我真的很好奇为什么我不能serializer.data直接编辑而不复制它.这个问题现在已经解决了,但如果有人能够仅仅因为好奇而提供有关问题的见解,那就太棒了.

dhk*_*hke 7

我用dir()检查了serializer.data,它只是一个python字典,所以我无法弄清楚为什么我无法修改该值.

虽然返回的值Serializer.data确实是字典,但Serializer.data不是简单的实例变量.

如果你看看rest_framework/serializers.py:

class Serializer(BaseSerializer):
    # [...]
    @property
    def data(self):
        ret = super(Serializer, self).data
        return ReturnDict(ret, serializer=self)
Run Code Online (Sandbox Code Playgroud)

ReturnDict继承自OrderedDict,但每次访问时仍然会得到一个新的字典Serializer.data.

真正的数据是_data,然而,由下划线注意您可能不希望修改,要么因为它并非是公众.该值被填补Serializer.to_representation(),你可以在视图集覆盖.

至于第二部分:ModelViewSet定义get_serializer()使用请求POST数据调用以创建要修改的序列化程序.我建议尝试在创建序列化程序之前更改输入数据.