当客户端仅提交一次表单时,Django 多次执行视图功能

Posted

技术标签:

【中文标题】当客户端仅提交一次表单时,Django 多次执行视图功能【英文标题】:Django executes the view functions many times when client has submitted a form just only once 【发布时间】:2015-06-29 22:51:21 【问题描述】:

我需要将用户的图像上传到服务器以便 django(1.8) 进行处理。 我确定客户只提交一次表格。但是后端执行了很多次相关的视图函数,当我提交了一个有点大的图像(大约2M)时返回504。

这是我的html

 <form action="/test/" method="POST" id="upload_form" enctype="multipart/form-data">
      % csrf_token %
      <a href="javascript:void(0);" class="addPic">
      <input id="choose_btn" class="btn" name="user_image"  type="file"></a>
 </form>
 <button type="button" id="upload_btn" class="btn btn-danger " data-loading-text="uploading..." autocomplete="off"> Upload!</button>

这是我的js(确保只有一个提交,灵感来自https://***.com/a/4473801/1902843):

$('#upload_btn').click( function () 
        var $btn = $(this).button('loading');
        $('#upload_form').submit(function(e)
            console.log("start submit");
            var $form = $(this);
            if ($form.data('submitted') === true) 
                // Previously submitted - don't submit again
                console.log("has submitted!");
                e.preventDefault();
             else 
                console.log("first submitted");
                // Mark it so that the next submit can be ignored
                $form.data('submitted', true);
            
        );
        $('#upload_form').submit();
    );

而我的后端视图函数是:

型号

class UserImage(models.Model):
    image = models.ImageField(upload_to='./user_image/%Y%m/%d', storage=ImageStorage(), blank=False)
    detect_result = models.TextField(max_length=1000, blank=True)

查看

@csrf_exempt
def test(request):
    # if use form's is_valid() function, it always return false. 
    # very weird, thus i annotate it
    # if request.method == 'POST':
    #     form = UploadFileForm(request.POST, request.FILES)
    #     if form.is_valid():
    user_image = request.FILES['user_image']
    im = UserImage(image=user_image)
    im.save() #after looking for log, it saved many times depending on image size?
    img_path = settings.MEDIA_URL + str(im.image)
    ...
    processing image
    ...

    return render_to_response('open.html', result_data)

【问题讨论】:

您的 javascript 代码中是否有两次提交调用:$('#upload_form').submit(function(e)... $('#upload_form').submit(); 【参考方案1】:

我会亲自将您的提交按钮放在表单中。

<form action="/test/" method="POST" id="upload_form" enctype="multipart/form-data">
    % csrf_token %
    <a href="javascript:void(0);" class="addPic">
    <input id="choose_btn" class="btn" name="user_image"  type="file"></a>
    <button type="button" id="upload_btn" class="btn btn-danger " data-loading-text="uploading..." autocomplete="off"> Upload!</button>
</form>

然后在#upload_btn 上使用事件侦听器,而不是触发点击。另外,只调用一次$('#upload_form').submit()

$('#upload_btn').on('click', function (e)   // Attach a click event listener
    // Check the form, display loading icon, etc
    // and when ready to submit the form ...
    $('#upload_form').submit();
);

【讨论】:

感谢您的回答,但这并不能解决我的问题。我确定检查服务器日志后只有一个提交,但视图的功能仍然运行多次......我认为这可能与图像的大小有关,因为它仅在我提交更大的图像时发生超过 400KB。

以上是关于当客户端仅提交一次表单时,Django 多次执行视图功能的主要内容,如果未能解决你的问题,请参考以下文章

Jquery 表单仅在您第一次提交时工作,而不是第二次

YUI.io (ajax) 和 Django - 更新只能工作一次,YUI 无法再次找到表单

在 Django 中一次提交中执行多个 save() 的最佳方法

在Django中一次提交中执行多个save()的最佳方法

Django 表单需要重新提交

如何避免表单重复提交