Django文件上传

6

这是 views 中的代码:

def index(request):
    if request.method == 'POST':
        a=request.POST
#        logging.debug(a["title"])
#        logging.debug(a["file"])
        #form = UploadFileForm()
        form = UploadFileForm(request.POST, request.FILES)
        #handle_uploaded_file(request.FILES['file'])
        if form.is_valid():
            handle_uploaded_file(request.FILES['file'])
            return HttpResponseRedirect('/')
    else:
        form = UploadFileForm()
    return render('upload.html', {'form': form})


def handle_uploaded_file(file):
#    logging.debug("upload_here")
    if file:
        destination = open('/tmp/'+file.name, 'wb+')
        #destination = open('/tmp', 'wb+')
        for chunk in file.chunks():
            destination.write(chunk)
        destination.close()

以下是 models 中的代码:

class UploadFileForm(forms.Form):
    title = forms.CharField(max_length=50)
    file  = forms.FileField(type="file")

这是upload.html中的代码:

{% block upload %}

<form enctype="multipart/form-data" method="post" action="/upload/">

    {% csrf_token %}
    <table>
        <tr><td>
            <input type="file" value="title" name="title" id="title" /><br />
            <input type="submit" value="Submit" id="Save"/>
        </td></tr>
    </table>
</form>
{% endblock %}

在我选择一个文件,然后按提交按钮时,出现错误:

在/upload/处的AttributeError

'WSGIRequest' 对象没有 'chunks' 属性

请求方法: POST 请求 URL: http://www.mywebsite.com/upload/ Django 版本: 1.3 异常类型: AttributeError 异常值:

'WSGIRequest' 对象没有 'chunks' 属性

异常位置: /usr/src/wpcms/views.py 中 handle_uploaded_file, 第63行

这里我做错了什么?是我忘记了设置行还是导入行? 谢谢。

settings.py 如下:

TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'cms.middleware.page.CurrentPageMiddleware',
    'cms.middleware.user.CurrentUserMiddleware',
    'cms.middleware.toolbar.ToolbarMiddleware',
    'cms.middleware.media.PlaceholderMediaMiddleware',
    'django.middleware.doc.XViewMiddleware',
    'django_authopenid.middleware.OpenIDMiddleware',
)

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.auth',
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    'django.core.context_processors.request',
    'django.core.context_processors.media',
    'cms.context_processors.media',
    'django_authopenid.context_processors.authopenid',
)

CMS_TEMPLATES = (
#    ('basic.html', 'Basic Template'),
#    ('template_1.html', 'Template One'),
#    ('template_2.html', 'Template Two'),
     ('home.html', gettext('Default')),
     ('about.html', gettext('About')),
#     ('blog.html', gettext('blog')),
     ('contact.html', gettext('Contact')),
)

ROOT_URLCONF = 'urls'

CMS_APPLICATIONS_URLS = (
    ('cmsplugin_news.urls', 'News'),
)

CMS_NAVIGATION_EXTENDERS = (
    ('cmsplugin_news.navigation.get_nodes', 'News navigation'),
)

THUMBNAIL_PROCESSORS = (
    'easy_thumbnails.processors.colorspace',
    'easy_thumbnails.processors.autocrop',
    #'easy_thumbnails.processors.scale_and_crop',
    'filer.thumbnail_processors.scale_and_crop_with_subject_location',
    'easy_thumbnails.processors.filters',
)

CMS_MODERATOR = False

TEMPLATE_DIRS = (
    os.path.join(PROJECT_DIR, 'templates'),
)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.admin',
    'django.contrib.comments',
    'registration',
    'django_authopenid',
    'cms',
    'menus',
    'mptt',
    'appmedia',
    'south',
    'cms.plugins.text',
    'cms.plugins.picture',
    'cms.plugins.link',
    'cms.plugins.file',
    'easy_thumbnails',
    'filer',
    'cmsplugin_filer_file',
    'cmsplugin_filer_folder',
    'cmsplugin_filer_image',
    'cmsplugin_filer_teaser',
    'cmsplugin_filer_video',
    'cms.plugins.snippet',
    'cms.plugins.googlemap',
    'publisher',
    'reversion',
    'cms.plugins.teaser',
    'cms.plugins.video',
    'cms.plugins.twitter',
    'cmsplugin_facebook',
    'cmsplugin_news',
    'cmsplugin_comments',
    'captcha',
)
1个回答

10

有多个问题。这里是一个已修复的版本,可以正常工作:

1)更改您的模板以使用实际的表单:

<form enctype="multipart/form-data" method="post" action="/upload/">
   {% csrf_token %}   
   <table>
       {{form.as_table}}
    </table>
    <input type="submit" value="Submit" id="Save"/>
</form>

2) 更新你的表单,移除FileField中不必要的类型声明:

class UploadFileForm(forms.Form):
    title = forms.CharField(max_length=50)
    file  = forms.FileField()

3) 更新你的视图以添加CSRF:

def index(request):
    if request.method == 'POST':
        a=request.POST
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            handle_uploaded_file(request.FILES['file'])
            return HttpResponseRedirect('/')
    else:
        form = UploadFileForm()

    c = {'form': form}
    c.update(csrf(request))
    return render_to_response('upload.html', c)
希望这可以帮助你!

非常感谢。在视图中的CSRF也是一个启示。当我应用所有这些更改时,只出现提交按钮,文件选择字段不会出现。 - kirtcathey
我认为问题出在我的settings.py文件中...仍然出现相同的错误,表单数据没有出现在HTML中。我会将设置添加到问题中。 - kirtcathey
看起来你需要调试一下你的环境。以下是几个建议:1)将表单生成的HTML源代码与正常工作的进行比较,2)从WSGI切换到开发环境并尝试重现,3)通过添加“import pdb; pdb.set_trace()”在你的视图中添加Python调试,并检查请求中发生了什么 - 你可以在PDB会话中键入“request.FILES.keys()”以查看浏览器发送了哪些文件。 - mif
1
当我错误地输入了views时,我遇到了这个错误。我写成了request.FILE而不是request.FILES。 - Aslam Khan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接