4

我正在使用 django 1.5、python 2.7 和 jquery 1.9。我有一个表格,它正好有 2 个字段,即title 和 document。当我按下提交时,我希望用户选择的文档出现在 request.FILES 中,如视图所示。

当我提交常规表单(没有 ajax)时,这工作正常,但是使用 ajax 我没有在我的请求中获得文件字段。关于如何使用 ajax 上传文件的任何建议。

HTML:

<form enctype="multipart/form-data" action="{% url 'upload_document' %}" method="post" id="uploadForm">
    {% csrf_token %}
        <ul>
          <li>
            <div>Title</div>
            <input id="title" type="text" maxlength="200"/>
            <div class="error"></div>          
          </li>

          <li>
            <div>Upload File</div>
            <input id="document" type="file" size="15" />
            <div class="error"></div>
          </li>
        </ul>

      <input type="submit" value="submit"/></p>
</form>   

表格.PY:

class UploadForm( forms.Form ):
    document = forms.FileField()
    title = forms.CharField(max_length = 200)

    def clean(self):
        cleaned_data = super(UploadForm, self).clean()
        return cleaned_data

    def save(self, *args, **kwargs):
        title = self.cleaned_data['title']
        doc = self.cleaned_data['document']

        document = Document(title = title, document = doc)
        document.save()
        return document

脚本:

<script type="text/javascript">
    $("#uploadForm").submit(function(event){
      event.preventDefault();
      $.ajax({
        url : "{% url 'upload_document' %}",
        type: "POST",
        data : {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
                title: document.getElementById('title').value,
                //document: document: document.getElementById('document'),
        },
        dataType : "json",
        success: function( response ){
           if(response == "True"){
            // success
           }
           else {
            //append errors
           }
        }
      });
  }); 
</script>

意见.PY

def upload_document(request): 
    print request.POST
    print request.FILES
    if request.is_ajax():
        if request.method == 'POST':
            form = UploadForm(request.POST, request.FILES, user = request.user)

            if form.is_valid():
                form.save()
                return HttpResponse(simplejson.dumps('True'), mimetype = 'application/json' )
            else:
                errors = form.errors
                return HttpResponse(simplejson.dumps(errors), mimetype = 'application/json' )
4

2 回答 2

3

这个问题的答案并不是那么简单。首先,如果您打算支持旧浏览器,那么它确实会变得令人讨厌。您必须处理隐藏的 iframe 和一些 JavaScript 技巧。我建议使用一些著名的脚本,例如jQuery-File-Upload

但是世界在不断发展,包括 HTML5 在内的新技术不断涌现。在大多数现代浏览器(IE10+、FireFox3.6+、Chrome13+,参见:http ://caniuse.com/fileapi )中都有一个新的文件 API,可用于此目的。首先你需要一些 HTML:

<input type="file" id="file-select" />

然后你可以绑定到(例如)change事件:

$('#file-select').change( handleFileSelect );

最后是处理程序本身:

var data = {};

function createReaderHandler(name) {
  return function(ev) {
    data[name] = ev.target.result;
  };
}

function handleFileSelect(ev) {
  var files = ev.target.files; // FileList object

  // Loop through the FileList
  for (var i = 0; i < files.length; i++) {
    var file = files[i],
        name = file.name || file.fileName,
        reader = new FileReader();

    reader.onload = createReaderHandler(name);
    reader.readAsText(file);
  }
}

一旦数据被加载到 JavaScript 内存中(注意操作是异步的),您可以像任何其他数据一样通过 AJAX 发送它。还有更多选项:根据您的文件,您可以将其作为二进制数据读取.readAsBinaryString,依此类推。谷歌是你的朋友。:)

此外,我认为已经有很好的脚本用于上传文件并回退到旧方法。这个可能很有趣(没试过):

http://www.plupload.com/

于 2013-04-06T08:54:20.013 回答
0

我认为问题出在提交按钮上,将其更改为普通按钮,即<button type='button' id='submit'>submit</button>(默认情况下,表单中的所有按钮都是提交)和 ajax 为

$('#submit').on('click',function(){
    frm = $(this).parents('form')
    $.ajax({
          type: frm.attr('method'),
          dataType:'json',
          url: frm.attr('action'),
          data: frm.serialize(),
          async: false,
          success: function (data) {
              console.log('success')
          },
          error: function(data) {
              console.log("Something went wrong!");
          }
})

所有其他人都一样只要试试就行了

于 2018-04-20T05:34:32.537 回答