补丁资源如何与文件

时间:2016-03-04 08:19:59

标签: python django api rest tastypie

我有这个用户档案的模型和资源

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")

为了发送测试数据,我使用chrome-extention

send the PATHC query to my resource

2 个答案:

答案 0 :(得分:1)

这与您尝试执行的文件上传有关。无法以这种方式处理内容类型,您应该将文件转换为base64才能执行此操作。

检查此Github issue以获取有关如何将POST(或PATCH)文件继续运行到资源的更多信息。

此外,此stack与您的问题有关。

答案 1 :(得分:0)

  

这是DRF(django-rest-framework)中的一个问题,你可以查看Tom Christie的GitHub。问题以下面给出的解决方案结束。您还可以在issues存储库

djang-rest-framework页面上找到相同的解决方案

由于各种原因,Django只允许读取一次POST主体。由于正文使用类似文件的API公开,因此您无法再轻松读取该文件。此外,如果您已经读过数据,则无法更改上传文件处理程序。无法仅读取一次POST数据将失败,并且由于两个原因调试很棘手。

  • Django只会在您第二次访问正文时报告错误,所以 第一次访问时可能很难跟踪。
  • 无数不同的问题可能会导致这种情况。一种方法是打印 完整的追溯(只要数据获得traceback.print_stack()) 阅读(django/http/request.pyHttpRequest.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-framework确保

  

请求确实是POST,并且确实使用的是Content-Type   通过表格提交发送。

但这恰好是Django test client!的行为存在两种可能的修复:

禁用浏览器覆盖

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

更改Django测试客户端中的Content-Type

 from django.test import Client

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