上传文件验证的最佳方案

root
abc abc
  • 20 Jul

作者:梓羽文谲
链接:https://www.zhihu.com/quest...
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Django模型中自带的ImageField和FileField字段并不会也不能限制用户上传的图片或文件的格式和大小,这给Web APP开发带来了很大的安全隐患。当然你可以通过自定义form类中的clean的方法来添加对image或file字段进行验证,从而限制上传文件格式和大小,然而这并不是最佳处理方法,因为这意味者每次你的模型里包含了图片或文件字段,你都要自定义forms类,并添加clean方法,从而造成大量代码重复。一个处理该问题的最佳方式是扩展Django的FileFiled字段,在创建模型时直接设置可以接受的文件类型,并限定可以上传的文件的最大尺寸。你可以使用此代码段格式检查器。它的作用是它允许你指定允许上传的文件格式。并允许你设置要上传文件的文件大小限制。第一。在应用程序内创建一个名为formatChecker.py的文件,在该文件中,你的模型具有要接受某种文件类型的FileField。这是你的formatChecker.py:from django.db.models import FileField
from django.forms import forms
from django.template.defaultfilters import filesizeformat
from django.utils.translation import ugettextlazy 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", 0)

    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第二。在你的models.py中,添加以下内容:from formatChecker import ContentTypeRestrictedFileField然后,使用此“ ContentTypeRestrictedFileField”代替“ FileField”。例: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)你可以将“ max_upload_size”的值更改为所需的文件大小限制。你还可以将“ content_types”列表中的值更改为要接受的文件类型。发布于 2024-01-22 15:12​赞同 1​​添加评论​分享​收藏​喜欢收起​南风以南Python开发工程师,石油开发系研究生,公众号:不灵兔​ 关注