开发者

Django form validation, clean(), and file upload

Can someone illuminate me as to exactly when an uploaded file is actually written to the location returned by "upload_to" in the FileFiel开发者_开发技巧d, in particular with regards to the order of field, model, and form validation and cleaning?

Right now I have a "clean" method on my model which assumes the uploaded file is in place, so it can do some validation on it. It looks like the file isn't yet saved, and may just be held in a temporary location or in memory. If that is the case, how do I "open" it or find a path to it if I need to execute some external process/program to validate the file?

Thanks,

Ian


The form cleansing has nothing to do with actually saving the file, or with saving any other data for that matter. The file isn't saved until to you run the save() method of the model instance (note that if you use ModelName.objects.create() this save() method is called for you automatically).

The bound form will contain an open File object, so you should be able to do any validation on that object directly. For example:

form = MyForm(request.POST, request.FILES)
if form.is_valid():
    file_object = form.cleaned_data['myFile']
    #run any validation on the file_object, or define a clean_myFile() method 
    #  that will be run automatically when you call form.is_valid()

    model_inst = MyModel('my_file' = file_object,
                     #assign other attributes here....
                     )
    model_inst.save() #file is saved to disk here


What do you need to do on it? If your validation will work without a temporary file, you can access the data by calling read() on what your file field returns.

def clean_field(self):
    _file = self.cleaned_data.get('filefield')
    contents = _file.read()

If you do need it on the disk, you know where to go from here :) write it to a temporary location and do some magic on it!


Or write it as a custom form field. This is the basic idea how I go about verification of an MP3 file using the 'mutagen' library.

Notes:

  • first check the file size then if correct size write to tmp location.
  • Will write the file to temporary location specified in SETTINGS check its MP3 and then delete it.

The code:

from django import forms

import os
from mutagen.mp3 import MP3, HeaderNotFoundError, InvalidMPEGHeader

from django.conf import settings

class MP3FileField(forms.FileField):

    def clean(self, *args, **kwargs):
        super(MP3FileField, self).clean(*args, **kwargs)
        tmp_file = args[0]

        if tmp_file.size > 6600000:
            raise forms.ValidationError("File is too large.")

        file_path = getattr(settings,'FILE_UPLOAD_TEMP_DIR')+'/'+tmp_file.name

        destination = open(file_path, 'wb+')
        for chunk in tmp_file.chunks():
            destination.write(chunk)
        destination.close()

        try:
            audio = MP3(file_path)
            if audio.info.length > 300:
                os.remove(file_path)
                raise forms.ValidationError("MP3 is too long.")

        except (HeaderNotFoundError, InvalidMPEGHeader):
            os.remove(file_path)
            raise forms.ValidationError("File is not valid MP3 CBR/VBR format.")
        os.remove(file_path)
        return args
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜