2016-03-04 109 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')