只接受FileField中的某个文件类型,服务器sid

2024-04-20 03:43:59 发布

您现在位置:Python中文网/ 问答频道 /正文

如何限制FileField以一种优雅的方式(服务器端)只接受某种类型的文件(视频、音频、pdf等)?


Tags: 文件类型视频pdf方式服务器端音频filefield
3条回答

一个非常简单的方法是使用自定义验证器。

在应用程序的validators.py中:

def validate_file_extension(value):
    import os
    from django.core.exceptions import ValidationError
    ext = os.path.splitext(value.name)[1]  # [0] returns path+filename
    valid_extensions = ['.pdf', '.doc', '.docx', '.jpg', '.png', '.xlsx', '.xls']
    if not ext.lower() in valid_extensions:
        raise ValidationError(u'Unsupported file extension.')

那么在你的models.py中:

from .validators import validate_file_extension

。。。使用表单域的验证程序:

class Document(models.Model):
    file = models.FileField(upload_to="documents/%Y/%m/%d", validators=[validate_file_extension])

另请参见:How to limit file types on file uploads for ModelForms with FileFields?

版本1.11中的Django为模型字段添加了一个新的FileExtensionValidator,文档在这里:https://docs.djangoproject.com/en/dev/ref/validators/#fileextensionvalidator

如何验证文件扩展名的示例:

from django.core.validators import FileExtensionValidator
from django.db import models

class MyModel(models.Model):
    pdf_file = models.FileField(upload_to='foo/',
                                validators=[FileExtensionValidator(allowed_extensions=['pdf'])])

注意,此方法不安全。Django docs的引文:

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.

还有新的validate_image_file_extensionhttps://docs.djangoproject.com/en/dev/ref/validators/#validate-image-file-extension)用于验证图像扩展(使用枕头)。

有一个Django snippet这样做:

import os

from django import forms

class ExtFileField(forms.FileField):
    """
    Same as forms.FileField, but you can specify a file extension whitelist.

    >>> from django.core.files.uploadedfile import SimpleUploadedFile
    >>>
    >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
    >>>
    >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
    >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
    >>>
    >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
    Traceback (most recent call last):
    ...
    ValidationError: [u'Not allowed filetype!']
    """
    def __init__(self, *args, **kwargs):
        ext_whitelist = kwargs.pop("ext_whitelist")
        self.ext_whitelist = [i.lower() for i in ext_whitelist]

        super(ExtFileField, self).__init__(*args, **kwargs)

    def clean(self, *args, **kwargs):
        data = super(ExtFileField, self).clean(*args, **kwargs)
        filename = data.name
        ext = os.path.splitext(filename)[1]
        ext = ext.lower()
        if ext not in self.ext_whitelist:
            raise forms.ValidationError("Not allowed filetype!")

#-------------------------------------------------------------------------

if __name__ == "__main__":
    import doctest, datetime
    doctest.testmod()

相关问题 更多 >