Django限制用户上传文件格式与大小
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种方式。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」