i have django form (not modelform) required filefield. according the filefield documentation, validation of filefield should validate non-empty file data has been bound form, not seeing behavior. instead able submit form without file , form passes validation. expected behavior fail validation.
things work expected when file specified in form.
my form looks this:
class bucketuploadform(forms.form): file = forms.filefield(required=true) # required=true default, i'm being explicit def clean(self): upload_to = '/some/path' upload_to += self.cleaned_data['file'].name # raising keyerror
my view looks this:
def bucket_upload(request): if request.method == 'post': form = bucketuploadform(request.post, request.files) if form.is_valid(): # raising aforementioned keyerror when no file 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))
my template looks this:
<form action="" method="post" enctype="multipart/form-data"> {% csrf_token %} <table> {{ form }} </table> <input type="submit" value="upload" /> </form>
the traceback looks this:
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 , 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 @ /courses/a/b/assignments/c/sduckwo/upload exception value: 'file'
update
removing clean method bucketuploadform causes filefield's validation fail expected. however, need clean method other checks, removing permanently not option.
i've found modifying clean method this:
class bucketuploadform(forms.form): file = forms.filefield(required=true) # required=true default, 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 # raising keyerror
then validation fails expected, 2 error messages:
- 'no file or empty file given', raised bucketuploadform.clean()
- 'this field required', raised filefield.clean(), after in first place.
this tells me filefield.clean() raising validationerror, exception somehow being ignored unless bucketuploadform.clean() either not exist or raises validationerror.
so i'm maybe little closer end goal still confused.
i think i've seen before. anecdotal experience seems django not stop validation if field missing (e.g. call clean() if missing required fields). says required field missing not including field name in cleaned_data.
scott pointed out documented here:
for field, if field.clean() method raises validationerror, field-specific cleaning method not called. however, cleaning methods remaining fields still executed.
therefore, think solution program clean() method defensively checking if 'file' key in cleaned_data , if isn't, return cleaned_data is. django knows required field missing, is_valid() fail , no harm come.
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
Comments
Post a Comment