使用 Backbone 将文件上传到美味派?
Posted
技术标签:
【中文标题】使用 Backbone 将文件上传到美味派?【英文标题】:Uploading files to tastypie with Backbone? 【发布时间】:2013-04-22 20:37:17 【问题描述】:检查了一些其他问题,我认为我的美味派资源应该是这样的:
class MultipartResource(object):
def deserialize(self, request, data, format=None):
if not format:
format = request.META.get('CONTENT_TYPE', 'application/json')
if format == 'application/x-www-form-urlencoded':
return request.POST
if format.startswith('multipart'):
data = request.POST.copy()
data.update(request.FILES)
return data
return super(MultipartResource, self).deserialize(request, data, format)
class ImageResource(MultipartResource, ModelResource):
image = fields.FileField(attribute="image")
如果有错请告诉我。
假设以上是正确的,我没有得到的是传递给资源的内容。这是一个文件输入:
<input id="file" type="file" />
如果我有一个主干模型 img,我应该将图像设置为什么?
img.set("image", $("#file").val()); // tastypie doesn't store file, it stores a string
img.set("image", $("#file").files[0]); // get ""error_message": "'dict' object has no attribute '_committed'" ...
我应该将我的主干“图像”属性设置为什么,以便我可以通过 ajax 将文件上传到美味派?
【问题讨论】:
【参考方案1】:您可以覆盖sync
方法以使用FormData
api 进行序列化,以便能够将文件作为模型的属性提交。
请注意,它仅适用于现代浏览器。它适用于 Backbone 0.9.2,我建议检查默认的 Backbone.sync 并相应地采用这个想法。
function getValue (object, prop, args)
if (!(object && object[prop])) return null;
return _.isFunction(object[prop]) ?
object[prop].apply(object, args) :
object[prop];
var MultipartModel = Backbone.Model.extend(
sync: function (method, model, options)
var data
, methodMap =
'create': 'POST',
'update': 'PUT',
'delete': 'DELETE',
'read': 'GET'
, params =
type: methodMap[method],
dataType: 'json',
url: getValue(model, 'url') || this.urlError()
;
if (method == 'create' || method == 'update')
if (!!window.FormData)
data = new FormData();
$.each(model.toJSON(), function (name, value)
if ($.isArray(value))
if (value.length > 0)
$.each(value, function(index, item_value)
data.append(name, item_value);
)
else
data.append(name, value)
);
params.contentType = false;
params.processData = false;
else
data = model.toJSON();
params.contentType = "application/x-www-form-urlencoded";
params.processData = true;
params.data = data;
return $.ajax(_.extend(params, options));
,
urlError: function()
throw new Error('A "url" property or function must be specified');
);
这是上传视图的摘录,我使用<input type="file" name="file" multiple>
进行文件上传,因此用户可以选择多个文件。然后我监听 change 事件并使用collection.create
上传每个文件。
var MultipartCollection = Backbone.Collection.extend(model: MultipartModel);
var UploadView = Backbone.View.extend(
events:
"change input[name=file]": "changeEvent"
,
changeEvent: function (e)
this.uploadFiles(e.target.files);
// Empty file input value:
e.target.outerhtml = e.target.outerHTML;
,
uploadFiles: function (files)
_.each(files, this.uploadFile, this);
return this;
,
uploadFile: function (file)
this.collection.create(file: file);
return this;
)
【讨论】:
我还是一头雾水,我应该将什么传递给模型属性以便它接收文件?还是我总是必须将模型链接到表单?以上是关于使用 Backbone 将文件上传到美味派?的主要内容,如果未能解决你的问题,请参考以下文章