使用 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');
  

);

这是上传视图的摘录,我使用&lt;input type="file" name="file" multiple&gt; 进行文件上传,因此用户可以选择多个文件。然后我监听 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 将文件上传到美味派?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过tastepie上传文件/图像

树莓派 python 如何将本地文件上传到指定的服务器页面上

django 和backbone.js 问题

如何检查该用户是不是已通过来自美味派的身份验证?

树莓派里的文件复制到本地-scp命令

从树莓派上传文件到谷歌驱动器