通过ajax将文件上传到django

时间:2017-11-30 06:56:06

标签: javascript jquery ajax django

我在尝试使用ajax将文件上传到django时遇到了麻烦。上传过程以模态完成。

表格

<div class="modal fade bs-example-modal-lg" id="fileUploadModal" role="dialog" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span>
                </button>
                <h4 class="modal-title" id="myModalLabel2">Upload File</h4>
            </div>
            <div class="modal-body">
                <div class="modal-body">
                    {% crispy fileform %}
                </div>
            </div>
        </div>
    </div>
</div>

模态切换

<a data-toggle="modal" href="#fileUploadModal" data-id="0" role="button" class="btn btn-success btn-sm pull-right">
   <i class="fa fa-fw fa-cloud-upload"></i>
     Upload File
</a>

这就是我上传文件的方式

      $(document).ready(function(){
            var file = 0;

            $('#fileUploadModal').on('show.bs.modal', function(e) {
                file = $(e.relatedTarget).data('id');
                var form = $(e.currentTarget).find('form');

                $.ajax({
                    url: "{% url 'employee:ajax-file-upload' %}",
                    type: "POST",
                    data: $(form).serialize() + '&action=load&eid=' + employee + '&fid=' + file,

                    success: function(data) {
                        if (data['form_html']) {
                            $(form).html(data['form_html']);
                            $('.datepicker').datetimepicker({
                                format: 'YYYY-MM-DD'
                            });
                        }
                    }
                });
            });

            $(".container" ).on('click', '#submit-file-upload', function(e) {
                e.preventDefault();
                e.stopImmediatePropagation();

                var form = $(this).closest('form');

                $.ajax({
                    url: "{% url 'employee:ajax-file-upload' %}",
                    type: "POST",
                    data: $(form).serialize() + '&eid=' + employee + '&fid=' + file,

                    success: function(data) {
                        if (!(data['success'])) {
                            $(form).replaceWith(data['form_html']);
                            $('.datepicker').datetimepicker({
                                format: 'YYYY-MM-DD'
                            });
                        }
                        else {
                            location.reload();
                        }
                    }
                });
            });
        });

我的观点看起来像这样

@json_view
@login_required
def ajax_file_upload(request):
    if request.method == 'POST':
        action = request.POST.get('action')
        fid = int(request.POST.get('fid'))
        eid = int(request.POST.get('eid'))
        employee = Employee.objects.get(id=eid)

        if action == 'load':
            try:
                file = File.objects.get(id=fid)
                form = FileForm(instance=file)
            except:
                form = FileForm()
            context = {} 
            context.update(csrf(request))
            form_html = render_crispy_form(form, context=context)
            return {'success': True, 'form_html': form_html}        
        else:
            if fid == 0:
                form = FileForm(request.POST or None, request.FILES or None)
            else:
                file = File.objects.get(id=fid)
                form = FileForm(request.POST or None, request.FILES or None, instance=file)
            if form.is_valid():
                file = form.save(commit=False)
                file.employee = employee
                file.save()
                messages.add_message(request, messages.SUCCESS, 'File was successfully saved.')
                return {'success': True}

            context = {} 
            context.update(csrf(request)) 
            form_html = render_crispy_form(form, context=context)
            return {'success': False, 'form_html': form_html}

我真的无法让它发挥作用。我可以成功获取其他数据,但不能获取文件。当我点击提交时,它会刷新,并在文件上传部分中显示“此字段是必填项”。

我希望你能帮助我。感谢。

1 个答案:

答案 0 :(得分:0)

您的ajax调用仅发布表单数据,而不是文件:

data: $(form).serialize() + '&action=load&eid=' + employee + '&fid=' + file

我建议使用一个库(例如jquery.fileupload.js,但还有很多其他选项)来正确上传文件,因为这是一个非常复杂的操作:你必须设置multipart / related body格式,附上将文件作为application / octet-stream提交给你的请求,如果它被大块切成块等等......

例如,使用jquery.fileupload,上传文件非常简单:

$(function() {$('#fileupload').fileupload({
     dataType: 'json',
     formData: $(form).serialize()...
     done: function(e, data) {
         ... your success handling code ...
     }
});});

其中$('#fileupload')定位您的文件输入字段(<input type='file'>)。

乍一看django代码看起来很好。