I need to prevent any non-ASCII characters in uploaded files' names because the applications using the data cannot handle them. I want to display a simple validation error.
Normally I do this in the clean_<filefieldname> method on my ModelForm. It works, but the problem is that this is called after the file is uploaded (which makes sense because I may want to check file data etc).
In this case, however, I don't need the actual file data, just the name, and would like to validate it before anything is uploaded. Where can I do this (apart from modifying all my admin templates to do a client-side JS check)?
EDIT:
Following Ghopper21's answer I wrote this upload handler (and added it to the beginning of the list in settings.py):
class CheckFilenameUploadHandler(FileUploadHandler):
def receive_data_chunk(self, raw_data, start):
return raw_data, start
def file_complete(self, file_size):
return None
def new_file(self, field_name, file_name, content_type, content_length, charset):
try:
validate_string(file_name)
except ValidationError:
raise StopFutureHandlers
validate_string raises a ValidationError if the name is not ok. However, this gives me a timeout on the POST request, regardless of whether the filename is valid. I could't find any more detailed examples other than the UploadHandler doc on the django pages.
If I raise StopUpload instead of StopFutureHandlers, I get the same behaviour for correct files, but invalid files are actually not uploaded - but then I'm redirected to the model's list view instead of seeing a validation error, even though the clean method is implemented and I say "save and continue editing".
From what I can see the best approach is to use a custom upload handler that skips the actual uploading of the file data if the filename is invalid. You'd then still use the clean_<filefieldname> method to raise the validation error.
It's slightly annoying to have to check the filename in two places. But you can't do it all within the form anyhow, since Django uploads file data as soon as you access an HttpRequest objects's POST or FILE properties, which are what you pass in when creating a bound form.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With