注意:阅读本文需要了解Django的基本内容
Django文件存储系统
首先,Django默认是带有一个文件存储系统的,并不需要我们手写代码来读取前端发送过来的文件,然后再写到硬盘上的指定位置,该过程Django的文件系统会直接帮我们执行。
默认存储系统是 django.core.files.storage.FileSystemStorage
继承自 django.core.files.storage.Storage
(这个类是Django文件系统的基类,自定义文件系统有时需要继承自这个类)
FileField
本文仅使用FileField字段来讲述
首先要明确settings文件中的 MEDIA_URL 和 MEDIA_ROOT 的作用
`MEDIA_URL` 是寻找文件的url路径,类似 STATIC_URL
`MEDIA_ROOT` 则是上传文件要保存的目录
假设:
MEDIA_URL="/media/"
MEDIA_ROOT='/home/doc' # 即文件会存储到home目录下的media目录
创建好Django项目后,创建模型类,如下所示:
class MyModel(models.Model):
# 按下边设置upload_to文件将会被上传到 /home/doc/uploads 目录内
upload = models.FileField(upload_to='uploads/')
假设上传文件名是 1.txt
, 那么数据库中upload字段保存的将是 uploads/1.txt
,如果有重名,Django会自行给该文件名称后添加内容以保证文件能够存入服务器
在视图函数中调用该文件的方式如下:
def myview(request):
m = MyModel(id=1) # 获取一个模型类对象
file = m.upload # 得到的是一个 file 对象
# 常用属性
file.name # 文件名,如 1.txt
file.size # 文件大小
file.url # 下载文件时使用的url,如 /media/uploads/1.txt,前端可访问该路径下载该文件,实际文件存储位置在/home/doc下
file.path # 完整的绝对路径 /home/doc/1.txt
以上方式使用的是Django的默认文件存储系统
## 自定义文件存储系统
在应用目录下(或其他位置)新建文件 storage.py
,代码如下:
import os, time, random
from django.core.files.storage import FileSystemStorage
from django.conf import settings
class LiterDocStorage(FileSystemStorage):
"""目的用于自定义文件名,具体还有哪些参数方法,可以看官方文档,参考链接有给出"""
def __init__(self, location=settings.MEDIA_ROOT, base_url=settings.MEDIA_URL):
# 初始化,location
super(LiterDocStorage, self).__init__(location, base_url)
# 重写 _save方法,自定义文件名
def _save(self, name, content):
# name为上传文件名称
# 文件扩展名
ext = os.path.splitext(name)[1]
# 文件目录
d = os.path.dirname(name)
# 定义文件名,年月日时分秒随机数
fn = time.strftime('%Y%m%d%H%M%S')
fn = fn + '_%d' % random.randint(10000, 99999)
# 重写合成文件名
name = os.path.join(d, fn + ext)
# 调用父类方法,执行文件的保存
return super(LiterDocStorage, self)._save(name, content)
class MyModel(models.Model):
# 按下边设置upload_to文件将会被上传到 /home/doc/uploads 目录内,文件名自定义
upload = models.FileField(upload_to='uploads/', storage=LiterDocStorage())
以上设置后实现了随机自定义一个文件名,如果要实现其他功能,可自行添加
自定义django文件存储系统限制上传文件大小