我正在学习如何在 Django 中上传文件,在这里我遇到了一个应该是微不足道的问题,错误:
The submitted data was not a file. Check the encoding type on the form.
以下是详细信息。
注意:我也看过 Django Rest Framework ImageField ,我试过了
serializer = ImageSerializer(data=request.data, files=request.FILES)
但我明白了
TypeError:
__init__()got an unexpected keyword argument 'files'
我有一个 Image 模型,我想通过 Django REST 框架与之交互:
class Image(models.Model):
image = models.ImageField(upload_to='item_images')
owner = models.ForeignKey(
User, related_name='uploaded_item_images',
blank=False,
)
time_created = models.DateTimeField(auto_now_add=True)
class ImageSerializer(serializers.ModelSerializer):
image = serializers.ImageField(
max_length=None, use_url=True,
)
class Meta:
model = Image
fields = ("id", 'image', 'owner', 'time_created', )
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser',
),
前端(使用AngularJS和angular-restmod或$resource)用owner发送JSON数据和 image 的形式:
{"owner": 5, "image": "data:image/jpeg;base64,/9j/4QqdRXhpZgAATU0A..."}
在后端,request.data显示
{u'owner': 5, u'image': u'data:image/jpeg;base64,/9j/4QqdRXhpZgAATU0AKgAAA..."}
但随后 ImageSerializer(data=request.data).errors 显示错误
ReturnDict([('image', [u'The submitted data was not a file. Check the encoding type on the form.'])])
我想知道我应该怎么做才能修复这个错误?
编辑:JS 部分
相关的前端代码由两部分组成:一个angular-file-dnd directive(可用here)文件到页面和 angular-restmod,它提供了 CRUD 操作:
<!-- The template: according to angular-file-dnd, -->
<!-- it will store the dropped image into variable $scope.image -->
<div file-dropzone="[image/png, image/jpeg, image/gif]" file="image" class='method' data-max-file-size="3" file-name="imageFileName">
<div layout='row' layout-align='center'>
<i class="fa fa-upload" style='font-size:50px;'></i>
</div>
<div class='text-large'>Drap & drop your photo here</div>
</div>
# A simple `Image` `model` to perform `POST`
$scope.image_resource = Image.$build();
$scope.upload = function() {
console.log("uploading");
$scope.image_resource.image = $scope.image;
$scope.image_resource.owner = Auth.get_profile().user_id;
return $scope.image_resource.$save();
};
关于这个问题的更新:现在我切换到使用 ng-file-upload,它以正确的格式发送图像数据。
最佳答案
您遇到的问题是 Django REST 框架 expects files to be uploaded as multipart form data ,通过标准的文件上传方式。这是typically a file field ,但 JavaScript Blob object also works用于 AJAX。
您希望使用 base64 编码字符串而不是原始文件上传文件,is not supported by default .有 Base64ImageField out there 的实现,但最有希望的一个came by a pull request .
由于这些主要是为 Django REST framework 2.x 设计的,我已经改进了拉取请求中的一个,并创建了一个应该与 DRF 3 兼容的。
from rest_framework import serializers
class Base64ImageField(serializers.ImageField):
"""
A Django REST framework field for handling image-uploads through raw post data.
It uses base64 for encoding and decoding the contents of the file.
Heavily based on
https://github.com/tomchristie/django-rest-framework/pull/1268
Updated for Django REST framework 3.
"""
def to_internal_value(self, data):
from django.core.files.base import ContentFile
import base64
import six
import uuid
# Check if this is a base64 string
if isinstance(data, six.string_types):
# Check if the base64 string is in the "data:" format
if 'data:' in data and ';base64,' in data:
# Break out the header from the base64 content
header, data = data.split(';base64,')
# Try to decode the file. Return validation error if it fails.
try:
decoded_file = base64.b64decode(data)
except TypeError:
self.fail('invalid_image')
# Generate file name:
file_name = str(uuid.uuid4())[:12] # 12 characters are more than enough.
# Get the file name extension:
file_extension = self.get_file_extension(file_name, decoded_file)
complete_file_name = "%s.%s" % (file_name, file_extension, )
data = ContentFile(decoded_file, name=complete_file_name)
return super(Base64ImageField, self).to_internal_value(data)
def get_file_extension(self, file_name, decoded_file):
import imghdr
extension = imghdr.what(file_name, decoded_file)
extension = "jpg" if extension == "jpeg" else extension
return extension
这应该用于替换 Django REST 框架提供的标准 ImageField。所以你的序列化器会变成
class ImageSerializer(serializers.ModelSerializer):
image = Base64ImageField(
max_length=None, use_url=True,
)
class Meta:
model = Image
fields = ("id", 'image', 'owner', 'time_created', )
这应该允许您指定 base64 编码的字符串,或 Django REST 框架通常期望的标准 Blob 对象。
关于python - Django REST Framework 上传图片 : "The submitted data was not a file",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28036404/
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub
我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数