Django forms.FileField(required=True)为空时正在通过验证
我有一个Django表单(不是ModelForm)和一个必需的文件字段。根据,FileField的验证应该验证非空文件数据是否已绑定到表单,但我没有看到这种行为。相反,我可以在没有文件的情况下提交表单,并且表单通过了验证。预期的行为将是验证失败 当在表单中指定文件时,一切正常 我的表单如下所示:Django forms.FileField(required=True)为空时正在通过验证,django,django-forms,Django,Django Forms,我有一个Django表单(不是ModelForm)和一个必需的文件字段。根据,FileField的验证应该验证非空文件数据是否已绑定到表单,但我没有看到这种行为。相反,我可以在没有文件的情况下提交表单,并且表单通过了验证。预期的行为将是验证失败 当在表单中指定文件时,一切正常 我的表单如下所示: class BucketUploadForm(forms.Form): file = forms.FileField(required=True) # required=True is the d
class BucketUploadForm(forms.Form):
file = forms.FileField(required=True) # required=True is the default, but I'm being explicit
def clean(self):
upload_to = '/some/path'
upload_to += self.cleaned_data['file'].name # this is raising a KeyError
def bucket_upload(request):
if request.method == 'POST':
form = BucketUploadForm(request.POST, request.FILES)
if form.is_valid(): # this is raising the aforementioned KeyError when no file is submitted
do_stuff()
return HttpResponseRedirect(some_url)
else:
form = BucketUploadForm(initial=request.GET)
return render_to_response('handin/bucket_upload.html', {'form': form}, context_instance=RequestContext(request))
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<table>
{{ form }}
</table>
<input type="submit" value="Upload" />
</form>
Django Version: 1.3.1
Python Version: 2.7.3
Installed Applications:
['django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'django.contrib.admindocs',
'hgrepo',
'sshkey',
'handin',
'accounts']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware')
Traceback:
File "/usr/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python2.7/dist-packages/django/contrib/auth/decorators.py" in _wrapped_view
23. return view_func(request, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/django/views/decorators/http.py" in inner
45. return func(request, *args, **kwargs)
File "/home/sduckwo/projects/webhandin/webhandin/handin/views.py" in bucket_upload
461. if form.is_valid():
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in is_valid
121. return self.is_bound and not bool(self.errors)
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in _get_errors
112. self.full_clean()
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in full_clean
268. self._clean_form()
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in _clean_form
296. self.cleaned_data = self.clean()
File "/home/sduckwo/projects/webhandin/webhandin/handin/forms.py" in clean
116. upload_to += self.cleaned_data['file'].name
Exception Type: KeyError at /courses/a/b/assignments/c/sduckwo/upload
Exception Value: 'file'
class BucketUploadForm(forms.Form):
file = forms.FileField(required=True) # required=True is the default, but I'm being explicit
def clean(self):
if 'file' not in self.cleaned_data:
raise ValidationError('No file or empty file given')
upload_to = '/some/path'
upload_to += self.cleaned_data['file'].name # this is raising a KeyError
我的观点是这样的:
class BucketUploadForm(forms.Form):
file = forms.FileField(required=True) # required=True is the default, but I'm being explicit
def clean(self):
upload_to = '/some/path'
upload_to += self.cleaned_data['file'].name # this is raising a KeyError
def bucket_upload(request):
if request.method == 'POST':
form = BucketUploadForm(request.POST, request.FILES)
if form.is_valid(): # this is raising the aforementioned KeyError when no file is submitted
do_stuff()
return HttpResponseRedirect(some_url)
else:
form = BucketUploadForm(initial=request.GET)
return render_to_response('handin/bucket_upload.html', {'form': form}, context_instance=RequestContext(request))
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<table>
{{ form }}
</table>
<input type="submit" value="Upload" />
</form>
Django Version: 1.3.1
Python Version: 2.7.3
Installed Applications:
['django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'django.contrib.admindocs',
'hgrepo',
'sshkey',
'handin',
'accounts']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware')
Traceback:
File "/usr/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python2.7/dist-packages/django/contrib/auth/decorators.py" in _wrapped_view
23. return view_func(request, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/django/views/decorators/http.py" in inner
45. return func(request, *args, **kwargs)
File "/home/sduckwo/projects/webhandin/webhandin/handin/views.py" in bucket_upload
461. if form.is_valid():
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in is_valid
121. return self.is_bound and not bool(self.errors)
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in _get_errors
112. self.full_clean()
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in full_clean
268. self._clean_form()
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in _clean_form
296. self.cleaned_data = self.clean()
File "/home/sduckwo/projects/webhandin/webhandin/handin/forms.py" in clean
116. upload_to += self.cleaned_data['file'].name
Exception Type: KeyError at /courses/a/b/assignments/c/sduckwo/upload
Exception Value: 'file'
class BucketUploadForm(forms.Form):
file = forms.FileField(required=True) # required=True is the default, but I'm being explicit
def clean(self):
if 'file' not in self.cleaned_data:
raise ValidationError('No file or empty file given')
upload_to = '/some/path'
upload_to += self.cleaned_data['file'].name # this is raising a KeyError
我的模板如下所示:
class BucketUploadForm(forms.Form):
file = forms.FileField(required=True) # required=True is the default, but I'm being explicit
def clean(self):
upload_to = '/some/path'
upload_to += self.cleaned_data['file'].name # this is raising a KeyError
def bucket_upload(request):
if request.method == 'POST':
form = BucketUploadForm(request.POST, request.FILES)
if form.is_valid(): # this is raising the aforementioned KeyError when no file is submitted
do_stuff()
return HttpResponseRedirect(some_url)
else:
form = BucketUploadForm(initial=request.GET)
return render_to_response('handin/bucket_upload.html', {'form': form}, context_instance=RequestContext(request))
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<table>
{{ form }}
</table>
<input type="submit" value="Upload" />
</form>
Django Version: 1.3.1
Python Version: 2.7.3
Installed Applications:
['django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'django.contrib.admindocs',
'hgrepo',
'sshkey',
'handin',
'accounts']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware')
Traceback:
File "/usr/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python2.7/dist-packages/django/contrib/auth/decorators.py" in _wrapped_view
23. return view_func(request, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/django/views/decorators/http.py" in inner
45. return func(request, *args, **kwargs)
File "/home/sduckwo/projects/webhandin/webhandin/handin/views.py" in bucket_upload
461. if form.is_valid():
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in is_valid
121. return self.is_bound and not bool(self.errors)
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in _get_errors
112. self.full_clean()
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in full_clean
268. self._clean_form()
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in _clean_form
296. self.cleaned_data = self.clean()
File "/home/sduckwo/projects/webhandin/webhandin/handin/forms.py" in clean
116. upload_to += self.cleaned_data['file'].name
Exception Type: KeyError at /courses/a/b/assignments/c/sduckwo/upload
Exception Value: 'file'
class BucketUploadForm(forms.Form):
file = forms.FileField(required=True) # required=True is the default, but I'm being explicit
def clean(self):
if 'file' not in self.cleaned_data:
raise ValidationError('No file or empty file given')
upload_to = '/some/path'
upload_to += self.cleaned_data['file'].name # this is raising a KeyError
更新
从BucketUploadForm中删除clean方法会导致文件字段的验证按预期失败。但是,对于其他检查,我需要clean方法,因此永久删除它不是一个选项
我还发现,通过将clean方法修改为如下所示:
class BucketUploadForm(forms.Form):
file = forms.FileField(required=True) # required=True is the default, but I'm being explicit
def clean(self):
upload_to = '/some/path'
upload_to += self.cleaned_data['file'].name # this is raising a KeyError
def bucket_upload(request):
if request.method == 'POST':
form = BucketUploadForm(request.POST, request.FILES)
if form.is_valid(): # this is raising the aforementioned KeyError when no file is submitted
do_stuff()
return HttpResponseRedirect(some_url)
else:
form = BucketUploadForm(initial=request.GET)
return render_to_response('handin/bucket_upload.html', {'form': form}, context_instance=RequestContext(request))
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<table>
{{ form }}
</table>
<input type="submit" value="Upload" />
</form>
Django Version: 1.3.1
Python Version: 2.7.3
Installed Applications:
['django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'django.contrib.admindocs',
'hgrepo',
'sshkey',
'handin',
'accounts']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware')
Traceback:
File "/usr/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python2.7/dist-packages/django/contrib/auth/decorators.py" in _wrapped_view
23. return view_func(request, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/django/views/decorators/http.py" in inner
45. return func(request, *args, **kwargs)
File "/home/sduckwo/projects/webhandin/webhandin/handin/views.py" in bucket_upload
461. if form.is_valid():
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in is_valid
121. return self.is_bound and not bool(self.errors)
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in _get_errors
112. self.full_clean()
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in full_clean
268. self._clean_form()
File "/usr/lib/python2.7/dist-packages/django/forms/forms.py" in _clean_form
296. self.cleaned_data = self.clean()
File "/home/sduckwo/projects/webhandin/webhandin/handin/forms.py" in clean
116. upload_to += self.cleaned_data['file'].name
Exception Type: KeyError at /courses/a/b/assignments/c/sduckwo/upload
Exception Value: 'file'
class BucketUploadForm(forms.Form):
file = forms.FileField(required=True) # required=True is the default, but I'm being explicit
def clean(self):
if 'file' not in self.cleaned_data:
raise ValidationError('No file or empty file given')
upload_to = '/some/path'
upload_to += self.cleaned_data['file'].name # this is raising a KeyError
然后验证按预期失败,但我收到两条错误消息:
因此,现在我可能离我的最终目标有点近了,但仍然很困惑。这会引发关键错误,因为您必须先调用super的clean方法才能获得
self.cleaned\u数据集
def clean(self):
super(BucketUploadForm, self).clean()
upload_to = '/some/path'
upload_to += self.cleaned_data['file'].name
你应该看看怎么做。如果你使用Django的表单,这是一本非常有启发性的书
希望这有帮助 我想我以前见过这个。根据轶事经验,如果缺少字段,Django似乎不会停止验证(例如,即使缺少必需字段,它也会调用clean()。它表示,由于未在数据中包含字段名,因此缺少必需字段
斯科特指出,
对于任何字段,如果field.clean()方法引发ValidationError,则不会调用任何特定于字段的清理方法。但是,仍将执行所有剩余字段的清理方法
因此,我认为解决方案就是通过检查“file”键是否在cleaned_数据中来防御性地编写clean()方法,如果不在cleaned_数据中,只需按原样返回cleaned_数据即可。Django已经知道缺少必需的字段,因此is_valid()将失败,不会造成任何伤害
def clean(self):
upload_to = '/some/path'
if not 'file' in self.cleaned_data:
return self.cleaned_data
upload_to += self.cleaned_data['file'].name
我忘了提到我已经试着打电话给super's clean()。照你的建议去做没有用。还要注意,表单和字段验证文档中没有一个示例调用super的clean()方法。@ScottDuckworth:您的代码似乎还可以,您是否仔细检查了缩进?除此之外,我没有任何线索。