tags:

views:

631

answers:

2

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?

+2  A: 

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/

Jarret Hardie
I haven't written anything in a view. I'm using the "clean" method in my Form to do the validation, then testing using the default administration view. Isn't doing all of the validation in the Form the "Django way"?
Ty
It doesn't matter where you do it. You need to access request.FILES to get the temporary file as the docs show. You can do this inside the Form class if you want.
Brian Neal
I updated my answer with instructions on how to get the uploaded file object from inside the form itself since, in your case, the form.is_valid() needs the file.
Jarret Hardie
Just make sure you've bound the form to the files with request.FILES in your view.
Jarret Hardie
Thanks for your help. I'd assume that the administration view would bind the form using request.FILES automatically, no? I'll be sure to do it myself when I write a view of my own.
Ty
A: 

thank you, only read() welldone