django 文件上载时,FILES始终为空

zqry0prt  于 2022-12-27  发布在  Go
关注(0)|答案(6)|浏览(144)

我完全被这个问题难住了,我一定是在做一些难以置信的愚蠢的事情。我试图简单地上传一个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

我的views.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 })

我已经花了几个小时寻找解决方案,但似乎都不起作用。I have the enctype set correctly(我认为)、I am using input type 'submit' for the form,并且我正在将表单数据绑定到我的模型(没关系,因为request.FILES是空的)。我还尝试在表单操作中使用直接url(action ='/report/showreport/'),但这并没有什么不同。
我也意识到上面的代码应该是request.FILES ['grades_csv']来匹配表单的输入id......但是这也没关系,因为request.FILES是空的。
在尝试调试时,我在视图中的if request.method ==“POST”之前设置了一个pdb跟踪。使用控制台,我可以看到我的request.POST不包括我隐藏的“testing”输入,并且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']}>

如果我试图访问www.example.com中的request.FILESviews.py不检查表单是否有效,则会出现以下错误:

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

我很难理解为什么我不能让它工作--看起来应该很简单。我可以使用pdb手动创建和写入项目目录中的文件,所以我不认为权限是问题所在...问题出在表单上?

z9smfwbn

z9smfwbn1#

检查是否已将enctype属性添加到form标记中。
官方文件示例:<form enctype="multipart/form-data" method="post" action="/foo/">

xkrw2x1b

xkrw2x1b2#

我希望你已经解决了这个问题。我有完全相同的问题,我发现我没有名称属性在输入标记
<input type="file" id="grade_csv" />,即您的输入。
如果它没有名字,django就不会接受它。所以添加名字属性,这样它就能很好地工作了。

r6vfmomb

r6vfmomb3#

我也遇到了这个问题,并为此困惑了一段时间。我的错误是相同的--我在input字段上缺少必要的字段。
为了查看实际需要的字段是什么,在本例中,一个非常好的做法是:

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

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

xfyts7mz

xfyts7mz4#

<input type="file" id="grade_csv" name="name" />

您必须在输入字段中添加 name

btqmn9zl

btqmn9zl5#

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

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

如果我加载一个调试器并实际检查对象,它不是空的,并且包含了我所期望的数据,这在两种情况下是完全相同的对象,调试器显示FILES为填充的,然后当我继续时,print显示它为空。
所以,如果你和我一样,想先了解一下对象,也许不要依赖MultiValueDict的字符串表示,但我不能解释bug的来源,因为MultiValueDict只是dict的子类,使用dict__str__

pnwntuvh

pnwntuvh6#

这里有两件事要确定:
1.表单标记应包含属性**“enctype=“multipart/form-data”**
1.每个文件字段都应具有**“name”**属性

相关问题