将文件发送到 django 时出现 Keyerror/MultiValueDictKeyError
Posted
技术标签:
【中文标题】将文件发送到 django 时出现 Keyerror/MultiValueDictKeyError【英文标题】:Keyerror/MultiValueDictKeyError while sending file to django 【发布时间】: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">×</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"
【问题讨论】:
【参考方案1】:您应该将enctype="multipart/form-data"
放在<form>
标记中,而不是<input>
标记中。
<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"
放入<form>
并从<input>
中删除,但它在后端和前端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)
的打印输出是什么?以上是关于将文件发送到 django 时出现 Keyerror/MultiValueDictKeyError的主要内容,如果未能解决你的问题,请参考以下文章
在 django 项目中删除文件时出现 403 FORBIDDEN
尝试向 API 发送 POST 请求时出现属性错误 - Django
尝试使用 Django 发送电子邮件时出现“[Errno 101] 网络无法访问”