2016-03-04 108 views
1

我有這樣的模式和資源爲用戶配置文件如何與文件補丁資源

class Profile(AbstractBaseUser, PermissionsMixin): 
    email = models.EmailField(blank=False, null=False, unique=True) 
    avatar = models.ImageField(blank=True, null=True) 

class ProfileResource(ModelResource): 
    class Meta: 
     queryset = Profile.objects.all() 
     resource_name = 'profiles' 
     allowed_methods = ['get', 'patch'] 

當我有嘗試修補這個資源,我得到異常:

RawPostDataException("You cannot access body after reading from request's data stream")

要發送測試數據我使用鉻擴展

send the PATHC query to my resource

回答

1

這是與您正在嘗試執行的文件上傳相關。內容類型不能用這種方式處理,您應該將文件轉換爲base64才能完成此操作。

請查看此Github issue以瞭解有關如何在POST(或PATCH)文件上繼續處理資源的更多信息。

另外,這個stack與您的問題有關。

+0

謝謝!這是很棒的解決方案! – Dmitry

0

這是DRF(django-rest-framework)中的一個問題,您可以在Tom Christie的GitHub上進行檢查。下面給出的解決方案關閉了問題。您也可以找到關於issuesdjang-rest-framework

各種原因相同的解決方案,Django的只允許讀取POST的身體一次。由於正文是暴露在類似文件的API中,因此無法再輕鬆讀取文件。另外,如果您已經閱讀了數據,則無法更改上傳文件處理程序。無法只讀取一次POST數據將會失敗,並且出於兩個原因調試很棘手。

  • 的Django只報告了錯誤,您訪問的身體,第二次,所以 它可以是很難跟蹤它第一次被訪問。
  • 無數不同的問題都可能導致這種情況。一種方法是打印 完整回溯(與traceback.print_stack())每當數據獲取 讀取(在django/http/request.py:。HttpRequest.readHttpRequest.readline)這是我是如何做到的,也許還有其他 方式

所以,你是否在你的代碼中訪問了request.method?你在使用Django測試客戶端嗎?如果是這樣的話,可能是HTTP header based method overriding踢過了。這個特性允許瀏覽器模擬除GET/POST之外的請求,爲此,django-rest-framework查看隱藏的表單字段,例如<input type="hidden" name="_method" value="DELETE">。通過POST請求,這些信息位於請求正文中,因此django-rest-framework必須讀取請求正文。

此功能enabled by default,但Django的REST的架構保證了

要求確實是POST和確實使用的Content-Type將 在表單提交發送。

但是,這恰好是Django test client!兩種可能的修復行爲存在:

禁用瀏覽器覆蓋

REST_FRAMEWORK = { 
'FORM_METHOD_OVERRIDE': None, 
'FORM_CONTENT_OVERRIDE': None, 
'FORM_CONTENTTYPE_OVERRIDE': None 
} 

更改的內容類型在Django測試客戶端

from django.test import Client 

client = Client() 
response = client.post(url, content_type='application/json')