Django (audio) File Validation

后端 未结 1 382
鱼传尺愫
鱼传尺愫 2020-12-08 15:25

I\'m experimenting with a site that will allow users to upload audio files. I\'ve read every doc that I can get my hands on but can\'t find much about validating files

相关标签:
1条回答
  • 2020-12-08 16:02

    You want to validate the file before it gets written to disk. When you upload a file, the form gets validated then the uploaded file gets passed to a handler/method that deals with the actual writing to the disk on your server. So in between these two operations, you want to perform some custom validation to make sure it's a valid audio file

    You could:

    • check if the the file is less then a certain size (good practice)
    • then check if the submitted file has a certain content type (i.e. an audio file)
      • this is pretty useless as someone could easily spoof it
    • then check that the file ends in a certain extension (or extensions)
      • this is also pretty useless
    • try read the file and see if it's actually audio

    (I haven't tested this code)

    models.py

    class UserSong(models.Model):
        title = models.CharField(max_length=100)
        audio_file = models.FileField()
    

    forms.py

    class UserSongForm(forms.ModelForm):
         # Add some custom validation to our file field
         def clean_audio_file(self):
             file = self.cleaned_data.get('audio_file',False):
             if file:
                 if file._size > 4*1024*1024:
                       raise ValidationError("Audio file too large ( > 4mb )")
                 if not file.content-type in ["audio/mpeg","audio/..."]:
                       raise ValidationError("Content-Type is not mpeg")
                 if not os.path.splitext(file.name)[1] in [".mp3",".wav" ...]:
                       raise ValidationError("Doesn't have proper extension")
                 # Here we need to now to read the file and see if it's actually 
                 # a valid audio file. I don't know what the best library is to 
                 # to do this
                 if not some_lib.is_audio(file.content):
                       raise ValidationError("Not a valid audio file")
                 return file
             else:
                 raise ValidationError("Couldn't read uploaded file")
    

    views.py from utils import handle_uploaded_file

    def upload_file(request):
        if request.method == 'POST':
            form = UserSongForm(request.POST, request.FILES)
            if form.is_valid():
                # If we are here, the above file validation has completed
                # so we can now write the file to disk
                handle_uploaded_file(request.FILES['file'])
                return HttpResponseRedirect('/success/url/')
        else:
            form = UploadFileForm()
        return render_to_response('upload.html', {'form': form})
    

    utils.py

    # from django's docs
    def handle_uploaded_file(f):
        ext = os.path.splitext(f.name)[1]
        destination = open('some/file/name%s'%(ext), 'wb+')
        for chunk in f.chunks():
            destination.write(chunk)
        destination.close()
    

    https://docs.djangoproject.com/en/dev/topics/http/file-uploads/#file-uploads https://docs.djangoproject.com/en/dev/ref/forms/fields/#filefield https://docs.djangoproject.com/en/dev/ref/files/file/#django.core.files.File

    0 讨论(0)
提交回复
热议问题