我一直在尝试更改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

我用dir() checkout 了serializer.data,它只是一个python字典,所以我不知道为什么我不能修改该值。作为测试,我尝试添加额外的值,但这也不起作用
# this doesnt work
serializer.data['some_new_field'] = 'test'

编辑

另一方面,我可以复制数据并进行编辑
fake_data = serializer.data.copy()
fake_data['old_value'] = 'new value'

但是,它始终无法验证
serializer = MyModelSerializer(data=fake_data)
serializer.is_valid() # returns false

编辑编辑:

好的,所以验证错误是由Django返回SimpleLazyObject引起的。现在,当我执行数据副本时,一切都可以正常工作,但是我很好奇为什么不能不复制就不能直接编辑serializer.data。现在已经解决了问题,但是如果有人可以出于好奇而提供有关此问题的见解,那将是非常棒的。

最佳答案


尽管从Serializer.data返回的值确实是一个字典,但是Serializer.data不是简单的实例变量。
如果您查看 rest_framework/serializers.py :

class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
    # [...]
    @property
    def data(self):
        ret = super().data
        return ReturnDict(ret, serializer=self)
ReturnDict 继承自 OrderedDict ,但是每次访问Serializer.data仍然会得到一个新的字典。
实际数据位于 _data 中,但是如下划线所示,您可能也不想修改它,因为它不打算公开。这些值由Serializer.to_representation()填充,您可以在 View 集上覆盖它。
至于第二部分:ModelViewSet定义与请求POST数据一起调用的get_serializer(),以创建要修改的序列化程序。我建议尝试在创建序列化程序之前更改输入数据。

关于python - 覆盖Django REST Framework中的serializer.data,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29383945/

10-11 04:11