如何用文件修补资源
How patch resource with file
我有用户配置文件的模型和资源
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
It was one of the issues in DRF(django-rest-framework) you can check on GitHub of Tom Christie. Issue was closed with the solution given below. You can also find same solution on issues page of djang-rest-framework repository
由于各种原因,Django 只允许读取 POST 主体一次。由于 body 暴露在类似文件 API 中,因此您无法轻松再次读取该文件。此外,如果您已经读取了数据,您将无法更改上传文件处理程序。只读取一次POST数据就会失败,调试起来比较棘手,原因有二。
- Django 仅在您第二次访问正文时报告其错误,因此
第一次访问时可能很难跟踪。
- 无数不同的问题都可能导致这种情况。一种方法是打印
完整的回溯(使用
traceback.print_stack())
每当数据获取
阅读(在 django/http/request.py
: HttpRequest.read
和
HttpRequest.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 确保
request is indeed POST and is indeed using a Content-Type that would
be sent on a form submission.
但这正是 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')
这与您尝试进行的文件上传有关。无法以这种方式处理内容类型,您应该将文件转换为 base64 才能执行此操作。
查看此 Github issue 以获取有关如何继续将 POST(或 PATCH)文件添加到您的资源的更多信息。
此外,这个stack与您的问题有关。
我有用户配置文件的模型和资源
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
It was one of the issues in DRF(django-rest-framework) you can check on GitHub of Tom Christie. Issue was closed with the solution given below. You can also find same solution on issues page of djang-rest-framework repository
由于各种原因,Django 只允许读取 POST 主体一次。由于 body 暴露在类似文件 API 中,因此您无法轻松再次读取该文件。此外,如果您已经读取了数据,您将无法更改上传文件处理程序。只读取一次POST数据就会失败,调试起来比较棘手,原因有二。
- Django 仅在您第二次访问正文时报告其错误,因此 第一次访问时可能很难跟踪。
- 无数不同的问题都可能导致这种情况。一种方法是打印
完整的回溯(使用
traceback.print_stack())
每当数据获取 阅读(在django/http/request.py
:HttpRequest.read
和HttpRequest.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 确保
request is indeed POST and is indeed using a Content-Type that would be sent on a form submission.
但这正是 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')
这与您尝试进行的文件上传有关。无法以这种方式处理内容类型,您应该将文件转换为 base64 才能执行此操作。
查看此 Github issue 以获取有关如何继续将 POST(或 PATCH)文件添加到您的资源的更多信息。
此外,这个stack与您的问题有关。