使用ajax上传时缺少Django文件

Posted

技术标签:

【中文标题】使用ajax上传时缺少Django文件【英文标题】:Django File missing when upload with ajax 【发布时间】:2019-02-15 20:30:34 【问题描述】:

我从事项目 django (V2.1 + python 3.6) 上传文本文件。 我有一个要上传的文件的模板,但发送表单时文件丢失了;不知道怎么回事。

这是我的模型:

from django.db import models

class Document(models.Model):
    description = models.CharField(max_length=255, blank=True)
    document = models.FileField(upload_to='documents/')
    uploaded_at = models.DateTimeField(auto_now_add=True)

这是我的模板:

<form enctype="multipart/form-data" method="post" action="% url 'add_document' %" class="js-add-document-form">
  % csrf_token %
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
      <span aria-hidden="true">&times;</span>
    </button>
    <h4 class="modal-title">Add document</h4>
  </div>
  <div class="modal-body">
    % include 'books/includes/partial_doc_form.html' %
  </div>
  <div class="modal-footer">
    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    <button type="submit" class="btn btn-primary">ADD</button>
  </div>
</form>

这是我的看法:

def save_doc_form(request, form, template_name):
    data = dict()
    if request.method == 'POST':
        if form.is_valid():
            form.save()
            data['form_is_valid'] = True
            docs = Document.objects.all()
            data['html_doc_list'] = render_to_string('docs/includes/partial_docs_list.html', 
                'docs': docs
            )
        else:
            data['form_is_valid'] = False
    context = 'form': form
    data['html_form'] = render_to_string(template_name, context, request=request)
    return JsonResponse(data)


def doc_create(request):
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
    else:
        form = DocumentForm()
    return save_book_form(request, form, 'docss/includes/partial_docs_create.html')

这是我的 js 文件:

$(function () 
  /* Functions */
  var loadForm = function () 
    var btn = $(this);
    $.ajax(
      url: btn.attr("data-url"),
      type: 'get',
      dataType: 'json',
      beforeSend: function () 
        $("#modal-doc").modal("show");
      ,
      success: function (data) 
        $("#modal-doc .modal-content").html(data.html_form);
      
    );
  ;
  var saveForm = function () 
    var form = $(this);
    $.ajax(
      url: form.attr("action"),
      data: form.serialize(),
      type: form.attr("method"),
      dataType: 'json',
      success: function (data) 
        if (data.form_is_valid) 
          $("#doc-table tbody").html(data.html_docs_list);
          $("#modal-doc").modal("hide");
        
        else 
          $("#modal-doc .modal-content").html(data.html_form);
        
      
    );
    return false;
  ;
  /* Binding */
  // Create document
  $(".js-add-document").click(loadForm);
  $("#modal-doc").on("submit", ".js-add-document-form", saveForm);
);

一切似乎都正常,除了发送表单时,它不包含任何文件。 示例:当我做类似的事情时:

print('-----&gt;&gt;&gt;&gt;', form.cleaned_data['document']) 我得到None。 请帮忙 !我不知道我错了什么。

【问题讨论】:

【参考方案1】:

在@Hayden 的帮助下进行多次搜索后,我找到了解决方案:

我用 formData 上传 js:

$(function () 
  /* Functions */
  /** No change to LodForm **/

  var saveForm = function () 
    var form = $(this);
    var formData = new FormData(form[0]);
    $.ajax(
      url: form.attr("action"),
      data: formData,
      type: form.attr("method"),
      dataType: 'json',
      async: true,
      cache: false,
      contentType: false,
      enctype: form.attr("enctype"),
      processData: false,
      success: function (data) 
        if (data.form_is_valid) 
          $("#doc-table tbody").html(data.html_docs_list);
          $("#modal-doc").modal("hide");
        
        else 
          $("#modal-doc .modal-content").html(data.html_form);
        
      
    );
    return false;
  ;
  /* Binding */
  // Create document
  $(".js-add-document").click(loadForm);
  $("#modal-doc").on("submit", ".js-add-document-form", saveForm);
);

它的作用就像一个魅力,但还有很多其他的解决方案,就像这个page

【讨论】:

【参考方案2】:

jQuery form.serialize() 函数不能编码多部分正文,我推荐FormData API

【讨论】:

以上是关于使用ajax上传时缺少Django文件的主要内容,如果未能解决你的问题,请参考以下文章

上传文件后,如何在 Django 中使用 AJAX 更新表(与 JavaScript 链接)?

Django文件上传***

Django 使用ajax上传文件

Django框架 之 Form表单和Ajax上传文件

Django框架 之 Form表单和Ajax上传文件

Django ajax jquery 文件上传