14

我对此完全感到困惑,并且一定在做一些非常愚蠢的事情。我正在尝试简单地在 Django 项目上上传文件。问题似乎是没有表单数据被传递到服务器——只有 csrf 令牌。我在 Mac 上运行 Django 1.5.1、python 2.7、virtualenv,并使用内置的 Django 开发服务器。

我的 HTML 表单是:

{% load url from future %}

<form enctype="multipart/form-data" method="POST" action="{% url 'showreport' %}">
    {% csrf_token %}
    <label>Upload grade csv file: </label>
    <input type="hidden" id="testing" value="maybe" />
    <input type="file" id="grade_csv" />
    <input type="submit" value="Generate Report" />
</form>

我的模型:

from django.db import models

class Document(models.Model):
file = models.FileField(upload_to='/media/', blank=True, null=True)

我的forms.py:

from django import forms
from .models import Document

class DocumentForm(forms.Form):
"""
to handle uploading grades csv file
"""
class Meta:
    models = Document

我的意见.py:

def report(request):
"""
Process the CSV file to remove inactive students
Manipulate to get right JSON format
Chart the results
"""
if request.method == 'POST':
    form = DocumentForm( request.POST, request.FILES )
    if form.is_valid():
        newfile = Document( file = request.FILES['file'] )
        newfile.save()

        classdata = {}
        studentdata = {}

        return render( request, 'report/showreport.html', { 'classdata': classdata, 'studentdata': studentdata } )
else:
    form = UploadFileForm()

return render( request, 'report/index.html', { 'form': form })

我花了几个小时寻找解决方案,但似乎没有任何效果。我正确设置了 enctype(我认为),我使用输入类型“提交”作为表单,并将表单数据绑定到我的模型(没关系,因为 request.FILES 为空)。我还尝试在这个 Django newbie page的表单操作 (action='/report/showreport/') 中使用直接 url ,但这并没有什么不同。据我所知,没有其他脚本绑定到表单提交操作并覆盖默认操作。

我也意识到上面的代码应该最可能是 request.FILES['grades_csv'] 以匹配表单的输入 id ......但这也无关紧要,因为 request.FILES 是空的。

在尝试调试时,我在我的视图中在 if request.method == "POST" 之前设置了一个 pdb 跟踪。使用控制台,我可以看到我的 request.POST 不包括我隐藏的“测试”输入,并且 request.FILES 是空的。当我在浏览器中运行它时,它只是将我返回到我的表单页面,基本上说我的表单无效。我的 pdb 结果在这里:

(Pdb) request.FILES
(Pdb) <MultiValueDict: {}>
(Pdb) request.POST['testing']
(Pdb) *** MultiValueDictKeyError: "Key 'testing' not found in <QueryDict: {u'csrfmiddlewaretoken': [u'0tGCChxa3Po619dCi114Sb9jmWRt82aj']}>"
(Pdb) request.POST
<QueryDict: {u'csrfmiddlewaretoken': [u'0tGCChxa3Po619dCi114Sb9jmWRt82aj']}>

如果我尝试访问我的 views.py 中的 request.FILES 而不检查表单是否有效,我会收到以下错误:

"Key 'file' not found in <MultiValueDict: {}>"

我很难过,感谢任何关于为什么我不能让它工作的帮助——看起来它应该很简单。我可以使用 pdb 在我的项目目录中手动创建和写入文件,所以我认为权限不是问题……问题出在形式上?

4

4 回答 4

22

检查您是否已将enctype属性添加到form标签中。

来自官方文档的示例: <form enctype="multipart/form-data" method="post" action="/foo/">

于 2015-12-28T17:40:12.267 回答
3

我希望你已经解决了这个问题。我遇到了完全相同的问题,我发现输入标签中没有名称道具

<input type="file" id="grade_csv" />那是你的输入。

如果它没有名字,django 不会接受它。所以添加名称道具然后它会很好用。

于 2020-08-27T07:04:40.090 回答
2

我也有这个问题,困惑了一段时间。我的错误是一样的——我错过了该领域的必要字段input

为了查看实际需要的字段是什么,一个非常好的事情是,在这种情况下:

from base.forms import DocumentForm ## or put whatever the name is of the app, which is unspecified in the question
print DocumentForm()

这将打印您需要的 html,包括该对象所需的所有标签。我第一次错过的非常简洁的功能,但在文档中进行了概述。

于 2014-03-17T22:55:05.937 回答
0

我刚刚遇到一个奇怪的错误,当我打印出来时它显示为空:

print(request.FILES)
# Prints <MultiValueDict: {}>

如果我加载调试器并实际检查对象,它不是空的并且包含我期望的数据。在这两种情况下,这都是同一个对象。调试器显示FILES为已填充,然后当我继续时,print将其显示为空。

所以,如果你像我一样想先戳一下对象以了解它,也许不要依赖MultiValueDict's 字符串表示。我无法解释错误的来源,因为MultiValueDict它只是 's 的子类dict和使用dict's __str__

于 2022-01-21T22:28:12.380 回答