随笔 - 34  文章 - 0  评论 - 0  阅读 - 5666

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)。

  1.  
    from django.db.models import FileField
  2.  
    from django.forms import forms
  3.  
    from django.template.defaultfilters import filesizeformat
  4.  
     
  5.  
     
  6.  
    class RestrictedFileField(FileField):
  7.  
    """ max_upload_size:
  8.  
    2.5MB - 2621440
  9.  
    5MB - 5242880
  10.  
    10MB - 10485760
  11.  
    20MB - 20971520
  12.  
    50MB - 5242880
  13.  
    100MB 104857600
  14.  
    250MB - 214958080
  15.  
    500MB - 429916160
  16.  
    """
  17.  
    def __init__(self, *args, **kwargs):
  18.  
    self.content_types = kwargs.pop("content_types", [])
  19.  
    self.max_upload_size = kwargs.pop("max_upload_size", [])
  20.  
     
  21.  
    super().__init__(*args, **kwargs)
  22.  
     
  23.  
    def clean(self, *args, **kwargs):
  24.  
    data = super().clean(*args, **kwargs)
  25.  
    file = data.file
  26.  
     
  27.  
    try:
  28.  
    content_type = file.content_type
  29.  
    if content_type in self.content_types:
  30.  
    if file.size > self.max_upload_size:
  31.  
    raise forms.ValidationError('Please keep filesize under {}. Current filesize {}'
  32.  
    .format(filesizeformat(self.max_upload_size), filesizeformat(file.size)))
  33.  
    else:
  34.  
    raise forms.ValidationError('This file type is not allowed.')
  35.  
    except AttributeError:
  36.  
    pass
  37.  
    return data

如何使用扩展后的RestrictedFileField

首先你要从创建的fields.py里导入RestrictedFileField,然后在模型中按如下代码使用它。该字段可以用于文件,也可以用于图片。与ImageField和FileField相比,它多了content_types和max_upload_size选项,从此你再也不用担心用户上传文件时为所欲为啦。 这个字段是如此有用,说不定Django某一天会把它变成默认字段哦。小编我期待有那一天的到来。

  1.  
    from django.db import models
  2.  
    from .fields import RestrictedFileField
  3.  
     
  4.  
    class File(models.Model):
  5.  
    file = RestrictedFileField(upload_to=user_directory_path, max_length=100,
  6.  
    content_types=['application/pdf', 'application/excel', 'application/msword',
  7.  
    'text/plain', 'text/csv', 'application/zip',
  8.  
    max_upload_size=5242880,)
  9.  
     
  10.  
     
  11.  
     
  12.  
    class Image(models.Model):
  13.  
    file = RestrictedFileField(upload_to=user_directory_path, max_length=100,
  14.  
    content_types=['image/jpeg', 'image/gif', 'image/gif', 'image/bmp', 'image/tiff'],
  15.  
    max_upload_size=5242880,)

 

注意:

用户上传文件还要考虑其它安全因素,比如不同用户上传了文件名相同的文件怎么办?用户上传文件的应该放在哪里比较好?更多内容见Django自定义图片和文件上传路径(upload_to)的2种方式

 

posted on   ldx-wsj  阅读(512)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示