Django Ajax--如何解决 request.FILE 为空的问题?

76 阅读1分钟

在 Django 中,使用 Ajax 提交表单时,可能会遇到 request.FILES 为空的问题。这会导致无法上传文件。常见的问题是:

  • 使用了 jQuery v1.9.0 及以上的版本。jQuery v1.9.0 引入了一个新的 FormData 对象,该对象与 Django 的 request.FILES 不兼容。
  • 使用了 POSTGRESQL 9.1 及以上的版本。POSTGRESQL 9.1 及以上的版本默认启用了流媒体上传。这会导致 Django 无法正确处理文件上传。

2、解决方案

要解决这个问题,可以采取以下步骤:

  • 将 jQuery 版本降级到 v1.8.3 或更低版本。
  • 在 POSTGRESQL 中禁用流媒体上传。
# settings.py
# 解决 Django Ajax--request.FILE 为空的问题
# 将 stream_upload 设置为 False 来禁用流媒体上传
FILE_UPLOAD_HANDLERS = [
    'django.core.files.uploadhandler.TemporaryFileUploadHandler',
]

代码示例:

# views.py
def editevent_view(request, idevento):

    if request.method == 'GET' and request.is_ajax():
        formulario = FormImagen()
        ctx = {'form': formulario}
        return render_to_response('home/event/imagenform.html', ctx, context_instance=RequestContext(request))

    elif request.method == 'POST' and request.is_ajax():
        formulario = FormImagen(request.POST, request.FILES)

        if formulario.is_valid():
            formulario.save()
            return HttpResponse('very good')
        else:
            ctx = {'form': formulario}
            return render_to_response('home/event/imagenform.html', ctx, context_instance=RequestContext(request))

    elif request.method == 'GET':
        evento = Evento.objects.get(id=idevento)
        ctx = {'evento': evento}
        imagen = Imagen.objects.filter(evento=evento)
        return render_to_response('home/event/editEvent.html', ctx, context_instance=RequestContext(request))
<!-- imagenform.html -->
<form id="formulario" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit" class="btn btn-primary" onClick="enviar(this);">Guardar</button>
    <button type="reset" class="btn btn-primary">Limpiar</button>
</form>

<!-- editEvent.html -->
{% extends 'base.html' %}
{% block menu %}
{% endblock %}
{% block content %}
<div style="height:100%;" align="left">
    <h1 class="muted"> 编辑图片 </h1>
    <h2>{{ evento.nombre }}</h2>
    <div id="imagenes">
        <div id="menu">
            <button class="btn" onClick="subirImagen(this);">添加图片 <i class="icon-plus"></i></button>
            <div>
            <div id="contenedor">
                <ul class="thumbnails">
                    {% if imagen %}
                        {% for i in imagen %}
                            <li class="span4">
                                <img data-src="{{ i.photo }}" alt="">
                            </li>
                        {% endfor %}
                    {% endif %}
                </ul>
            </div>
        </div>
    </div>
</div>
{% endblock %}
{% block js %}
<script type="text/javascript">
    // 请求图片上传表单
    function subirImagen(e) {
        $.ajax({
            url: '/editevento/14/',
            type: 'GET',
            dataType: 'html',
            success: function (datos) {
                $('#contenedor').empty();
                $('#contenedor').append(datos);
            }
        });
    }

    // 提交图片上传表单
    function enviar(e) {
        $('#formulario').submit(function (evento) {
            evento.preventDefault();
            var datos_formulario = $(this).serialize();
            alert('event444os');
            $.ajax({
                url: '/editevento/14/',
                data: datos_formulario,
                type: 'POST',
                dataType: 'html',
                processData: false,
                cache: false,
                success: function (datos) {
                    $('#contenedor').empty();
                    $('#contenedor').append(datos);
                }
            });
        });
    }
</script>
{% endblock %}