Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: Open uploaded file while still in memory; In the Form Clean method?

Tags:

python

django

I need to validate the contents of an uploaded XML file in my Form clean method, but I'm unable to open the file for validation. It seams, in the clean method, the file hasn't yet been moved from memory (or the temporary directory) to the destination directory.

For example the following code doesn't work because the file hasn't been moved to that destination yet. It's still in memory (or the temporary directory):

xml_file = cleaned_data.get('xml_file')
xml_file_absolute = '%(1)s%(2)s' % {'1': settings.MEDIA_ROOT, '2': xml_file}
xml_size = str(os.path.getsize(xml_file_absolute))

When I look at the "cleaned_data" variable it shows this:

{'xml_file': <InMemoryUploadedFile: texting.nzb (application/octet-stream)>}

cleaned_data.get('xml_file') only returns "texting.nzb" as a string.

Is there another way to access the the file in memory (or the temporary directory)?


Again, this is in my Form's clean method that's tied into the default administration view. I've been told time and time again that all validation should be handled in a Form, not the view. Correct?

like image 799
Ty. Avatar asked Mar 11 '09 17:03

Ty.


1 Answers

I'm assuming that you've bound your form to the files using:

my_form = MyFormClass(request.POST, request.FILES)

If you have, once the form has been validated, you can access the file content itself using the request.FILES dictionary:

if my_form.is_valid():
    data = request.FILES['myfile'].read()

The request.FILES['myfile'] object is an UploadedFile object, so it supports file-like read/write operations.

If you need to access the file contents from within the form's clean method (or any method of the cleaning machinery), you are doing it right. cleaned_data.get('xml_file') returns an UploadedFile object. The __str__ method of that object just prints out the string, which is why you see only the file name. However, you can get access to the entire contents:

xml_file = myform.cleaned_data.get('xml_file')
print xml_file.read()

This section of the docs has some great examples: http://docs.djangoproject.com/en/dev/topics/http/file-uploads/

like image 167
Jarret Hardie Avatar answered Nov 01 '22 00:11

Jarret Hardie