https://blog.csdn.net/weixin_42134789/article/details/100012339
Django模型中自带的ImageField和FileField字段并不会也不能限制用户上传的图片或文件的格式和大小,这给Web APP开发带来了很大的安全隐患。当然你可以通过自定义form类中的clean的方法来添加对image或file字段进行验证,从而限制上传文件格式和大小,然而这并不是最佳处理方法,因为这意味者每次你的模型里包含了图片或文件字段,你都要自定义forms类,并添加clean方法,从而造成大量代码重复。一个处理该问题的最佳方式是扩展Django的FileFiled字段,在创建模型时直接设置可以接受的文件类型,并限定可以上传的文件的最大尺寸。本文教你如何扩展Django的FileField字段,并展示如何在模型中使用它,从而以最佳方式限制用户上传文件的格式与大小。
扩展FileField字段
首先在你APP文件夹内新建fields.py, 并添加如下代码(来自stackoverflow)。新扩展的FileField叫RestrictedFileField,继承了FileField类,并包含了额外的两个可选参数: 可接受的内容类型content_types和max_upload_size最大上传尺寸(比如5242880=5MB)。
- from django.db.models import FileField
- from django.forms import forms
- from django.template.defaultfilters import filesizeformat
- class RestrictedFileField(FileField):
- """ max_upload_size:
- 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().__init__(*args, **kwargs)
- def clean(self, *args, **kwargs):
- data = super().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 {}. Current filesize {}'
- .format(filesizeformat(self.max_upload_size), filesizeformat(file.size)))
- else:
- raise forms.ValidationError('This file type is not allowed.')
- except AttributeError:
- pass
- return data
如何使用扩展后的RestrictedFileField
首先你要从创建的fields.py里导入RestrictedFileField,然后在模型中按如下代码使用它。该字段可以用于文件,也可以用于图片。与ImageField和FileField相比,它多了content_types和max_upload_size选项,从此你再也不用担心用户上传文件时为所欲为啦。 这个字段是如此有用,说不定Django某一天会把它变成默认字段哦。小编我期待有那一天的到来。
- from django.db import models
- from .fields import RestrictedFileField
- class File(models.Model):
- file = RestrictedFileField(upload_to=user_directory_path, max_length=100,
- content_types=['application/pdf', 'application/excel', 'application/msword',
- 'text/plain', 'text/csv', 'application/zip',
- max_upload_size=5242880,)
- class Image(models.Model):
- file = RestrictedFileField(upload_to=user_directory_path, max_length=100,
- content_types=['image/jpeg', 'image/gif', 'image/gif', 'image/bmp', 'image/tiff'],
- max_upload_size=5242880,)
注意:
用户上传文件还要考虑其它安全因素,比如不同用户上传了文件名相同的文件怎么办?用户上传文件的应该放在哪里比较好?更多内容见Django自定义图片和文件上传路径(upload_to)的2种方式。
标签:max,upload,Django,content,文件格式,file,上传,size From: https://www.cnblogs.com/ldx-wsj/p/16867965.html