2015-04-01 64 views
7

我一直在試圖改變表單字段的值Django REST框架的管理面板,並且出於某種原因,更改從未發生。下面我有在Django REST框架中覆蓋serializer.data

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 

串行我檢查了serializer.data與dir(),它只是一個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引起的。當我對數據執行拷貝時,現在一切正常,但我真的很好奇爲什麼我不能直接編輯0​​而沒有拷貝它。這個問題現在已經解決了,但如果任何人都能爲了好奇而提供關於這個問題的見解,那就太棒了。

回答

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) 

ReturnDict繼承OrderedDict,但你仍然可以得到一個新的字典每次訪問Serializer.data時間。

real數據位於_data,但正如下劃線所示,您可能不想修改,因爲它不打算公開。值由Serializer.to_representation()填充,您可以在視圖上覆蓋這些值。

至於第二部分:ModelViewSet定義get_serializer()與請求POST數據一起調用以創建要修改的序列化程序。我建議嘗試在序列化程序創建之前更改輸入數據,而不是。