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

Viewed 84122

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

11 Answers

after I checked the accepted answer, I decided to share a tip based on Django documentation. There is already a validator for use to validate file extension. You don't need to rewrite your own custom function to validate whether your file extension is allowed or not.

https://docs.djangoproject.com/en/3.0/ref/validators/#fileextensionvalidator

Warning

Don’t rely on validation of the file extension to determine a file’s type. Files can be renamed to have any extension no matter what data they contain.

Just a minor tweak to @Thismatters answer since I can't comment. According to the README of python-magic:

recommend using at least the first 2048 bytes, as less can produce incorrect identification

So changing 1024 bytes to 2048 to read the contents of the file and get the mime type base from that can give the most accurate result, hence:

def validate_extension(file):
    valid_mime_types = ["application/pdf", "image/jpeg", "image/png", "image/jpg"]
    file_mime_type = magic.from_buffer(file.read(2048), mime=True) #  Changed this to 1024 to 2048

    if file_mime_type not in valid_mime_types:
        raise ValidationError("Unsupported file type.")

    valid_file_extensions = [".pdf", ".jpeg", ".png", ".jpg"]
    ext = os.path.splitext(file.name)[1]

    if ext.lower() not in valid_file_extensions:
        raise ValidationError("Unacceptable file extension.")
Related