2013-05-02 28 views
1

首先,我重寫我的視圖的get_object()方法,以URL解碼slug值(需要URL編碼,因爲該值包含斜線):django-rest-framework PUT重寫只讀中斷字段

class MyDetail(generics.RetrieveUpdateAPIView): 
    def get_object(self, queryset=None): 
     ... 
     slug = unquote(self.kwargs.get(self.slug_url_kwarg, None)) 

因此,雖然URL中的slug值是URL編碼的,但模型中的數據不是。 (也許有更好的方法來做到這一點;請讓我知道。)

無論如何,這似乎工作在一個GET找到正確的記錄。但是,當我嘗試執行PUT時,即使該字段包含在序列化程序的元類'read_only_fields成員中,該字段也會使用URL編碼版本進行更新。

這個問題似乎是在UpdateModelMixinpre_save()方法mixins.py行152:

def pre_save(self, obj): 
    ... 
    if pk: 
     setattr(obj, 'pk', pk) 

    if slug: 
     setattr(obj, slug_field, slug) 

這樣看來,這些都在這裏支持創建通過投入新的資源,爲https://github.com/tomchristie/django-rest-framework/issues/328提及。它不正確地處理我的案件嗎?還是有什麼我應該做的,以規避這種行爲?

回答

0

pk和/或slug在pre_save方法中設置,因爲它們隱含在URL中。 (與由串行器處理的請求數據相反)

如果您確實需要更改行爲,則可以通過覆蓋pre_save方法來更改行爲,儘管對於我而言這並不明顯,您爲什麼需要它有些不同。

the field gets updated with the URL-encoded version

當然這是正確的 - 如果對象確實存在,它已經從URL中擡起頭來由塞,然後設置URL中的蛞蝓領域實際上並不會改變它。如果對象不存在,那麼需要設置slug。

+0

slug值是URL編碼的,而模型數據不是; PUT將模型數據更新爲URL編碼版本。爲了清晰起見編輯了這個問題。 – Vic 2013-05-02 09:28:39

+0

哎呀。然後,你需要相應地覆蓋'pre_save'。就像'obj.slug = unquote(self.kwargs.get(self.slug_url_kwarg,None))' – 2013-05-02 10:17:47