Only accept a certain file type in FileField, server-side

前端 未结 10 647
日久生厌
日久生厌 2020-11-27 02:56

How can I restrict FileField to only accept a certain type of file (video, audio, pdf, etc.) in an elegant way, server-side?

10条回答
  •  北海茫月
    2020-11-27 03:14

    First. Create a file named formatChecker.py inside the app where the you have the model that has the FileField that you want to accept a certain file type.

    This is your formatChecker.py:

    from django.db.models import FileField
    from django.forms import forms
    from django.template.defaultfilters import filesizeformat
    from django.utils.translation import ugettext_lazy as _
    
    class ContentTypeRestrictedFileField(FileField):
        """
        Same as FileField, but you can specify:
            * content_types - list containing allowed content_types. Example: ['application/pdf', 'image/jpeg']
            * max_upload_size - a number indicating the maximum file size allowed for upload.
                2.5MB - 2621440
                5MB - 5242880
                10MB - 10485760
                20MB - 20971520
                50MB - 5242880
                100MB 104857600
                250MB - 214958080
                500MB - 429916160
    """
    def __init__(self, *args, **kwargs):
        self.content_types = kwargs.pop("content_types")
        self.max_upload_size = kwargs.pop("max_upload_size")
    
        super(ContentTypeRestrictedFileField, self).__init__(*args, **kwargs)
    
    def clean(self, *args, **kwargs):        
        data = super(ContentTypeRestrictedFileField, self).clean(*args, **kwargs)
    
        file = data.file
        try:
            content_type = file.content_type
            if content_type in self.content_types:
                if file._size > self.max_upload_size:
                    raise forms.ValidationError(_('Please keep filesize under %s. Current filesize %s') % (filesizeformat(self.max_upload_size), filesizeformat(file._size)))
            else:
                raise forms.ValidationError(_('Filetype not supported.'))
        except AttributeError:
            pass        
    
        return data
    

    Second. In your models.py, add this:

    from formatChecker import ContentTypeRestrictedFileField
    

    Then instead of using 'FileField', use this 'ContentTypeRestrictedFileField'.

    Example:

    class Stuff(models.Model):
        title = models.CharField(max_length=245)
        handout = ContentTypeRestrictedFileField(upload_to='uploads/', content_types=['video/x-msvideo', 'application/pdf', 'video/mp4', 'audio/mpeg', ],max_upload_size=5242880,blank=True, null=True)
    

    Those are the things you have to when you want to only accept a certain file type in FileField.

提交回复
热议问题