首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Django在文件上传中引发MultiValueDictKeyError

Django在文件上传中引发MultiValueDictKeyError
EN

Stack Overflow用户
提问于 2014-04-03 08:12:35
回答 4查看 42K关注 0票数 19

我已经咨询了很多论坛,我无法得到答案。我在Django应用程序中安装了一个文件上传以将数据保存到我的服务器中。但不起作用。相反,它会引发一个MultiValueDictKeyError。我猜问题是不存在request.FILES (因为它在request.FILES提到中引发了一个错误),所以文件上传不起作用。这是我的views.py:

代码语言:javascript
运行
复制
def list_files(request, phase_id):
    phase = get_object_or_404(Phase, pk=int(phase_id))  
    if request.method == 'POST':
    #form = DocumentForm(request.POST, request.FILES)
    form = DocumentForm(request.POST, request.FILES)
    if form.is_valid():
        newdoc = Document(docfile = request.FILES['docfile'], phase = phase_id)
        newdoc.save()
        doc_to_save = request.FILES['docfile']
        filename = doc_to_save._get_name()
        fd = open(settings.MEDIA_URL+'documents/'+str(filename),'wb')
        for chunk in doc_to_save.chunks():
            fd.write(chunk)
        fd.close()

        return HttpResponseRedirect(reverse('list_files')) 
    else:
        form = DocumentForm()

    documents = Document.objects.filter(phase=phase_id)

    return render_to_response('teams_test/list_files.html',{'documents': documents, 'form':form, 'phase':phase}, context_instance = RequestContext(request)
    )

Forms.py中的文档表单:

代码语言:javascript
运行
复制
class DocumentForm(forms.ModelForm):
    docfile = forms.FileField(label='Select a file', help_text='max. 42 megabytes')
    class Meta:
    model = Document

Models.py中的类文档:

代码语言:javascript
运行
复制
class Document(models.Model):
    docfile = models.FileField(upload_to='documents')
    phase = models.ForeignKey(Phase)

最后,我的html代码:

代码语言:javascript
运行
复制
{% extends "layouts/app.html" %}
{% load i18n  user %}

{% block title %}{% trans "Files list" %}{% endblock %}
{% block robots %}noindex,nofollow{% endblock %}


{% block page%}

<div id="page" class="container">
    <div class="header prepend-2 span-20 append-2 last whiteboard">
        <h2 style="margin-left:-40px">{{ phase.name }} files</h2>

        {% if documents %}
        <ul>
        {% for document in documents %}
        <li><a href="{{ document.docfile.url }}">{{ document.docfile.name }}
        {% endfor %}
        </ul>
    {% else %}
        <p>No documents.</p>
    {% endif %}

        <form action="{% url list_files phase.id %}" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <input id="file" type="file" />
        <input id="submit" type="submit" value="Upload file" />
        </form>
  </div> 
</div>
{% endblock %}

我的回溯说:

代码语言:javascript
运行
复制
Exception Type: MultiValueDictKeyError
Exception Value:    "Key 'docfile' not found in <MultiValueDict: {}>"
my_dir/views.py in list_files
    newdoc = Document(docfile = request.FILES['docfile'], phase = phase_id) 

我的QueryDict是空的:

代码语言:javascript
运行
复制
POST:<QueryDict: {u'csrfmiddlewaretoken': [u'UZSwiLaJ78PqSjwSlh3srGReICzTEWY1']}>

为什么?我做错了什么?

提前谢谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-04-03 08:42:57

您需要将multipart/form_data更改为multipart/form-data --这就是为什么request.FILES是空的:由于输入错误,表单并没有按照Django所期望的方式发送东西。编辑:现在已经完成了

更新1:另外,不要直接访问request.FILES,而是尝试依赖于模型表单的默认行为,因为这样它就会被适当地作为上传处理。ie,newdoc = form.save()应该完成您需要的所有工作,快速查看它--当模型表单可以为您保存文件时,是否有特定的原因可以手动保存该文件?

更新2:啊,听着:你没有给你的文件上传元素指定名字

从医生那里:

HttpRequest.FILES一个类似字典的对象,包含所有上传的文件.文件中的每个键都是来自<input type="file" name="" />的名称。文件中的每个值都是一个UploadedFile。

所以,你需要改变

代码语言:javascript
运行
复制
<input id="file" type="file" />

或者,默认Django约定

代码语言:javascript
运行
复制
<input id="id_docfile" type="file" name="docfile"/>

实际上,使用Django表单呈现实际字段通常更好,即使您已经超越了整个{{form.as_p}}方法:

代码语言:javascript
运行
复制
{{form.docfile}}

PS。如果您还没有完全阅读它们,我衷心建议您花时间浏览所有的表格文件

票数 20
EN

Stack Overflow用户

发布于 2015-10-06 15:02:59

修改Post方法

代码语言:javascript
运行
复制
<form action="" method="post" enctype="multipart/form-data">{% csrf_token %}
票数 10
EN

Stack Overflow用户

发布于 2019-07-31 07:00:46

因为更多的人尝试了上面的方法,但仍然想不出解决办法。我所做的是:

views.py

代码语言:javascript
运行
复制
if request.method == 'POST':
    doc = request.FILES #returns a dict-like object
    doc_name = doc['filename']
    ...
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22831576

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档