Django 1.1.1 处理 multipart/form-data 时崩溃
初始故事
我正在尝试通过一个简单的表单实现文件上传(这里贴的是简化版,但重要的部分都在):
<form method="POST" action="" enctype="multipart/form-data">
<input type="file" name="up_file" size="50">
<input type="hidden" name="cpk" value="{{c.pk}}">
<input type="submit" name="btn_submit">
</form>
现在,运行在 wsgi 下的服务器脚本收到了空的 request.FILES和request.POST字典,所以我决定切换到开发服务器来调试。
令人惊讶的是,当我输入request.POST和request.FILES并按下回车时,ipdb 调试器就卡住了……另一方面,当我从标签中去掉enctype="multipart/form-data"时,我可以查看request.POST和request.FILES,但当然这时request.FILES是空的。
(另外,去掉enctype="multipart/form-data"似乎也解决了 wsgi 的问题……)
更新
我尝试了 Opera 10 和 Firefox 3.5 的所有组合,enctype="multipart/form-data"和没有 multipart/form-data,以及开发服务器和 mod_wsgi。结果是,enctype="multipart/form-data"导致了问题。所以现在我打算去查看 Django 的 bug 跟踪器,看看这是否是一个已知的问题。
同时,也许这里有人可以给我指个方向。
1 个回答
你可能需要提供你的视图和表单代码,因为我们在Django 1.1.1中使用了带有enctype="multipart/form-data"
的表单上传,并且效果很好。
下面这个简单的应用程序在开发服务器上运行得非常顺利。
views.py
from django import forms
from django.shortcuts import render_to_response
class UploadForm(forms.Form):
cpk = forms.CharField(max_length=256)
f = forms.FileField()
def my_upload_view(request):
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES)
if form.is_valid():
print "Got cpk",form.cleaned_data['cpk']
print "Got file",request.FILES['f'].read()
else:
form = UploadForm()
return render_to_response('upload.html', {'form':form})
upload.html
<html>
<body>
<form enctype="multipart/form-data" method="post">
{{ form.f }}
{{ form.cpk }}
<input type="submit" />
</form>
</body>
</html>
我使用Django的表单实例来渲染文件输入框,但它生成了一个非常常见的<input type="file" name="f" id="id_f" />
。
使用这个示例,我可以在开发服务器的终端上看到文件的内容(我测试了一个简单的文本文件)。我可以推荐的一些注意事项和测试方法包括:
- 确保你上传的文件小于
settings.FILE_UPLOAD_MAX_MEMORY_SIZE
(默认是2.5 MB) - 仔细检查一下你是否定义了任何自定义的文件上传处理程序,这可能会影响上传过程(
settings.FILE_UPLOAD_HANDLERS
) - 尝试上传一个非常简单的文件(比如一个小文本文件),看看问题是否依然存在
- 使用工具检查原始的HTTP请求/响应流量(firebug可以帮你做到这一点,还有一些独立的应用程序可以作为代理来帮助你)……有时候,当你看到原始流量时,解决方案会一下子显现出来。
如果你还没有找到,Django文件上传文档里有很多示例。