【问题标题】:Keyerror/MultiValueDictKeyError while sending file to django将文件发送到 django 时出现 Keyerror/MultiValueDictKeyError
【发布时间】:2020-08-28 08:31:39
【问题描述】:

我将表单数据发送到 django api,表单数据也包含文件。当我通过 AJAX 将数据发送到 django 时,MultiValueDict 为 {} 空,我得到文件的 KeyError。我在没有发送文件的情况下进行了测试,但当我发送文件时它不起作用。

index.html [前端]

<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal" style="background-color:#00d1b2;border-color: transparent;color: #fff;font-size:20px;font-family:sans-serif;">Create Auto-Label Project</button>
<div class="modal" id="myModal" >
    <div class="modal-background"></div>
        <div class="modal-card" style="width:800px;">
        <header class="modal-card-head">
            <p class="modal-card-title">Create Auot-Label Project</p>
            <button type="button" aria-label="close" class="delete" data-dismiss="modal">&times;</button>

        </header>

        <section class="modal-card-body">

        <form  method="POST" id="upload" name="upload"  action="http://API_LINK">
            <div class="field">
               <label class="label">Project Name</label>
               <div class="control">
                   <input type="text" name="project_name" id="project_name" required="required" placeholder="Project name" class="input">

                </div>

                <p class="help is-danger"></p>

            </div>

            <div class="field">
                <label class="label">Description</label>
                <div class="control">
                    <textarea name="description" id="description" required="required" placeholder="Project description" class="textarea"></textarea>

                </div>

                <p class="help is-danger"></p>

            </div>

            <div class="field">
                <label class="label">Project Type</label>
                <div class="control">
                    <select name="project_type" id="project_type" required="required">
                        <option value="" selected="selected">---------</option>
                        <option value="DocumentClassification">document classification</option>
                        <option value="SequenceLabeling">sequence labeling</option>
                        <option value="Seq2seq">sequence to sequence</option>

                    </select>

                </div>

                <p class="help is-danger"></p>

            </div>

            <div class="field">
                <label class="label">Model Type</label>
                <div class="control">
                    <select name="model_name" id="model_name" required="required">
                        <option value="" selected="selected">---------</option>
                        <option value="sn">Simple NER</option>
                        <option value="mn">Bio-NER</option>
                        <option value="sa">Sentiment Analysis</option>
                    </select>

                </div>

                <p class="help is-danger"></p>

            </div>
            <div class="field">
                <label class="label">Guideline</label>
                <div class="control">
                    <textarea name="guideline" id="guideline" required="required" placeholder="Project guideline" class="textarea"></textarea>
                </div>

                <p class="help is-danger"></p>

            </div>

            <div class="field">
                <label class="label">Upload File</label>
                <div class="control">
                    <input type="file" required="required" id="file" name="myfile"  enctype="multipart/form-data" /><br><br>
                </div>
            </div>
            <div class="field">
               <label class="label">Confirm User Name</label>
               <div class="control">
                   <input type="text" name="username" id="username" required="required" placeholder="User Name" class="input">
              </div>
          </div>
          <div class="field">
              <label class="label">Confirm Password</label>
              <div class="control">
                  <input type="password" name="password" id="password" required="required" placeholder="Password" class="input">
              </div>
          </div>

          <footer class="modal-card-foot pt20 pb20 pr20 pl20 has-background-white-ter">
                <button type="submit" class="btn btn-success">Create <span class="fa fa-arrow-right"></span></button>
                <button class="button" data-dismiss="modal">Cancel</button>

          </footer>

      </form>

      </section>
    </div>

</div>

<script>
    $(document).ready(function() {
        $('form').submit(function(event) {
            var formData = {
                'project_name': $('input[name=project_name]').val(),
                'project_type': $('select[name=project_type]').val(),
                'guideline': $('textarea[name=guideline]').val(),
                'description': $('textarea[name=description]').val(),
                'model_name': $('select[name=model_name]').val(),
                'username': $('input[name=username]').val(),
                'password': $('input[name=password]').val(),
                'myfile': $('input[name=myfile]').val(),
        };

        $.ajax({
            type: 'POST',
            url: API_LINK,
            data: formData,
            crossDomain: true,
            dataType: 'json',
            encode: true

        }).done(function(data) {
                console.log(data); 
        });
        event.preventDefault();
    });
});
</script>

views.py [Django API 视图]

@csrf_exempt
def post_auto_label(request):
    if request.method == 'POST':
        print(request.FILES)
        myfile = request.FILES['myfile']
        project_name = request.POST.get('project_name')
        project_type = request.POST.get('project_type')
        guideline = request.POST.get('guideline')
        description = request.POST.get('description')
        model_name = request.POST.get('model_name')
        username = request.POST.get('username')
        password = request.POST.get('password')

        fs=FileSystemStorage()
        filename = fs.save(myfile.name, myfile)
        file_path = os.path.abspath("media/"+filename)

        if check_project_exist_or_not(username, password, project_name):
            print("Project already exist")
            if upload_labeled_data(username, password, project_name, model_name, 
                                file_path):
                return JsonResponse({"status": "Project created successfully."})
            else:
                return JsonResponse({"status": "Project can't be created. \
                Either you're not authenticated to create project or check the \
                file you are trying to upload."})

        else:
            if project_creation(username, password, project_name, description, 
        project_type, guideline):
                print("created project....")
                if upload_labeled_data(username, password, project_name, model_name, 
                                file_path):
                    return JsonResponse({"status": "Project created successfully."})
                else:
                    return JsonResponse({"status": "Project can't be created. Either \
                    you're not authenticated to create project or check the file you \
                    are trying to upload."})
            else:
                return JsonResponse({"status": "Project failed to create, check \
                username or password"})

在后端 Django 显示以下错误:

KeyError: 'myfile'
During handling of the above exception, another exception occurred:
django.utils.datastructures.MultiValueDictKeyError: 'myfile'

在前端

failed to load resource: the server respond with a status of 500

我的formdata在console.log()中显示如下

Object
description: "jlsfj",
guideline: "jfslfsjlow",
model_name: "sn",
myfile: "C:\fakepath\file.txt",
password: "password"
project_name: "name",
project_type: "lfsjl",
username: "user"

【问题讨论】:

    标签: javascript html jquery django ajax


    【解决方案1】:

    您应该将enctype="multipart/form-data" 放在&lt;form&gt; 标记中,而不是&lt;input&gt; 标记中。

    <form method="post" enctype="multipart/form-data" ....>
    

    也不要错过安装django-cors-headers

    pip install django-cors-headers
    

    然后将其添加到您安装的应用程序中:

    INSTALLED_APPS = [
        ...
        'corsheaders',
        ...
    ]
    
    
    MIDDLEWARE = [
        'corsheaders.middleware.CorsMiddleware',
        'django.middleware.common.CommonMiddleware',
        ....
    ]
    
    CORS_ORIGIN_ALLOW_ALL = True
    

    【讨论】:

    • 我尝试将enctype="multipart/form-data" 放入&lt;form&gt; 并从&lt;input&gt; 中删除,但它在后端和前端console.log 中显示相同的错误Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at API_LINK跨度>
    • @Alok 不要错过更改为您的网址 action="http://API_LINK" => 我认为该网址无效。
    • 我通过 Postman 测试了 api 是否正常,API_LINK 是正确的,和我在 postman 中使用的一样。
    • 我已经添加了这个库来避免 cors 问题,现在 cors 问题消失了,但 KeyError 仍然存在。
    • @Alok 和print(request.FILES) 的打印输出是什么?
    猜你喜欢
    • 1970-01-01
    • 2011-04-25
    • 2021-06-15
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 2014-05-14
    • 2019-08-01
    • 1970-01-01
    相关资源
    最近更新 更多