Django 通过Ajax上传文件

Page content

在上传文件到Django Server时,如果前端页面依赖Django form模板,耦合会较多,不便于异常处理和前后端分离。

我们可以通过新建FormData,用Ajax请求上传文件到Django后端,实现文件上传的前后端分离。

前端代码

file_upload.html

  <!-- with semantic UI and jQuery-->
  <form id="id_ajax_upload_form" class="ui form" method="post" onkeypress="return event.keyCode !== 13;">
        <div class="field">
            <label>User IDs:</label>
            <input type="file" id="user_ids" name="user_ids"/>
        </div>
      {% csrf_token %}
      <button class="upload ui teal button">Upload</button>
  </form>

Ajax Request

    $('.upload').click(function (e) {
        var form = $('form')[0];
        var formData = new FormData(form);

        if (form.checkValidity()) {
            e.preventDefault();
            $.ajax({
                url: '/upload',
                type: 'POST',
                data: formData,
                success: function (data) {
                    if (data.success) {
                        console.log(data);
                        alert('Success');
                    } else alert('Fail ' + data.errors);
                },
                enctype: 'multipart/form-data',
                cache: false,
                contentType: false,
                processData: false
            });
        }
    }

后端代码

在Django后端,可以直接从request.FILES读取上传的文件,示例如下:

def upload(request):
    my_file = request.FILES.get('my_file')  # File object
    ...
    return {'success': True}

或者是基于form对象来处理,示例如下:

form.py

from django import forms


class MyForm(forms.Form):
    my_file = forms.FileField(allow_empty_file=False)

view.py

from django.shortcuts import render
from django.http import JsonResponse
from .forms import MyForm


def upload(request):
    if request.method == 'POST':
       form = MyForm(request.POST, request.FILES)
       if form.is_valid():
           form.save()
           return JsonResponse({'success': True, 'message': 'Uploaded Successfully'})
       else:
           return JsonResponse({'success': False, 'errors': form.errors})
    else:
        return render(request, 'file_upload.html', {'form': MyForm})

参考