Django默认使用的文件存储系统'django.core.files.storage.FileSystemStorage'是一个本地存储系统,由settings中的DEFAULT_FILE_STORAGE值确定。

class FileSystemStorage(location=Nonebase_url=Nonefile_permissions_mode=Nonedirectory_permissions_mode=None)

FileSystemStorage类继承自Storage类,location是存储文件的绝对路径,默认值是settings中的MEDIA_ROOT值,base_url默认值是settings中的MEDIA_URL值。

当定义location参数时,可以无视MEDIA_ROOT值来存储文件:

from django.db import models
from django.core.files.storage import FileSystemStorage fs = FileSystemStorage(location='/media/photos') class Car(models.Model):
...
photo = models.ImageField(storage=fs)

这样文件会存储在/media/photos文件夹。

可以直接使用Django的文件存储系统来存储文件:

>>> from django.core.files.storage import default_storage
>>> from django.core.files.base import ContentFile >>> path = default_storage.save('/path/to/file', ContentFile('new content'))
>>> path
'/path/to/file' >>> default_storage.size(path)
11
>>> default_storage.open(path).read()
'new content' >>> default_storage.delete(path)
>>> default_storage.exists(path)
False

可以从FileSystemStorage类的_save方法看下上传文件是怎么存储的:

    def _save(self, name, content):
full_path = self.path(name) # Create any intermediate directories that do not exist.
# Note that there is a race between os.path.exists and os.makedirs:
# if os.makedirs fails with EEXIST, the directory was created
# concurrently, and we can continue normally. Refs #16082.
directory = os.path.dirname(full_path)
if not os.path.exists(directory):
try:
if self.directory_permissions_mode is not None:
# os.makedirs applies the global umask, so we reset it,
# for consistency with file_permissions_mode behavior.
old_umask = os.umask(0)
try:
os.makedirs(directory, self.directory_permissions_mode)
finally:
os.umask(old_umask)
else:
os.makedirs(directory)
except OSError as e:
if e.errno != errno.EEXIST:
raise
if not os.path.isdir(directory):
raise IOError("%s exists and is not a directory." % directory) # There's a potential race condition between get_available_name and
# saving the file; it's possible that two threads might return the
# same name, at which point all sorts of fun happens. So we need to
# try to create the file, but if it already exists we have to go back
# to get_available_name() and try again. while True:
try:
# This file has a file path that we can move.
if hasattr(content, 'temporary_file_path'):
file_move_safe(content.temporary_file_path(), full_path) # This is a normal uploadedfile that we can stream.
else:
# This fun binary flag incantation makes os.open throw an
# OSError if the file already exists before we open it.
flags = (os.O_WRONLY | os.O_CREAT | os.O_EXCL |
getattr(os, 'O_BINARY', 0))
# The current umask value is masked out by os.open!
fd = os.open(full_path, flags, 0o666)
_file = None
try:
locks.lock(fd, locks.LOCK_EX)
for chunk in content.chunks():
if _file is None:
mode = 'wb' if isinstance(chunk, bytes) else 'wt'
_file = os.fdopen(fd, mode)
_file.write(chunk)
finally:
locks.unlock(fd)
if _file is not None:
_file.close()
else:
os.close(fd)
except OSError as e:
if e.errno == errno.EEXIST:
# Ooops, the file exists. We need a new file name.
name = self.get_available_name(name)
full_path = self.path(name)
else:
raise
else:
# OK, the file save worked. Break out of the loop.
break if self.file_permissions_mode is not None:
os.chmod(full_path, self.file_permissions_mode) # Store filenames with forward slashes, even on Windows.
return force_text(name.replace('\\', '/'))

方法中可以看出,先判断文件存储的目录是否存在,如果不存在,使用os.mkdirs()依次创建目录。

根据directory_permissions_mode参数来确定创建的目录的权限,应该为(0777 &~umask)。

然后使用os.open()创建文件,flags参数为(os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, 'O_BINARY', 0)),

这样当文件已存在时,则报EEXIST异常,使用get_available_name()方法重新确定文件的名字。

mode为0o666,权限为(0666 &~umask)。

content为FILE对象,如一切正常,使用FILE.chunks()依次将内容写入文件。

最后,根据file_permissions_mode参数,修改创建文件的权限。

Django文件存储(一)默认存储系统的更多相关文章

  1. Django文件存储(二)定制存储系统

    要自己写一个存储系统,可以依照以下步骤: 1.写一个继承自django.core.files.storage.Storage的子类. from django.core.files.storage im ...

  2. android 开发-数据存储之文件存储

    android的文件存储是通过android的文件系统对数据进行临时的保存操作,并不是持久化数据,例如网络上下载某些图片.音频.视频文件等.如缓存文件将会在清理应用缓存的时候被清除,或者是应用卸载的时 ...

  3. django中云存储静态文件

    Django自带文件存储系统存储在本地文件夹,如果我们将文件存储在云端,需要自定义文件存储系统. 自定义文件存储系统需要继承django.core.files.storage.Storage from ...

  4. django 自定义存储上传文件的文件名

    一.需求: Django实现自定义文件名存储文件 使文件名看起来统一 避免收到中文文件导致传输.存储等问题 相同的文件也需要使用不同的文件名 二.实现思路: 思路: 生成14位随机字母加数字.后10位 ...

  5. PostgreSQL的存储系统二:REDOLOG文件存储结构二

    REDOLOG文件里的用户数据和数据文件里的用户数据存储结构相同 几个月前同事给台湾一家公司培训<pg9 ad admin>时,有个学员提及WAL里记录的内容为Query时的SQL语句(比 ...

  6. 修改Jupyter Notebook默认文件存储路径(已安装Anaconda)

    https://blog.csdn.net/weixin_44799144/article/details/91823079 修改Jupyter Notebook默认文件存储路径首先,安装好Anaco ...

  7. 使用Docker跑MySQL 作为Django的存储后端

    Docker的好处不科普了,用过的都说好. 不想污染自己开发机器上的文件环境,本萌新使用Docker运行Mysql,Redis来作为Django的存储后端和缓存. 在第一次安装过程中,我遇到了一些问题 ...

  8. Hadoop小文件存储方案

    原文地址:https://www.cnblogs.com/ballwql/p/8944025.html HDFS总体架构 在介绍文件存储方案之前,我觉得有必要先介绍下关于HDFS存储架构方面的一些知识 ...

  9. (转)FastDFS文件存储

    一.FastDFS介绍 FastDFS开源地址:https://github.com/happyfish100 参考:分布式文件系统FastDFS设计原理 参考:FastDFS分布式文件系统 个人封装 ...

随机推荐

  1. 用Python自动发送邮件

    用Python自动发送邮件     最近需要在服务器上处理一些耗时比较长的任务,因此想到利用python写一个自动发送邮件的脚本,在任务执行完毕后发送邮件通知我.以下代码以163邮箱为例: 开通163 ...

  2. 2.2使用urllib的简单传输

    使用urllib传输文件 from urllib.request import urlopen filename = 'new_1.py' password = 'password' #如果设置密码 ...

  3. SQL-45 将titles_test表名修改为titles_2017。

    题目描述 将titles_test表名修改为titles_2017.CREATE TABLE IF NOT EXISTS titles_test (id int(11) not null primar ...

  4. spring中classpath

    http://blog.csdn.net/wlwlwlwl015/article/details/48134763 Maven 项目的 classpath 理解 applicationContext. ...

  5. vue学习笔记 - 篇2

    1.借助Vue.extend()方法创建组件 注意点 var Aaa = Vue.extend({ template: "<h1>这是标题</h1>" }) ...

  6. Locust 参数化

    概述: 和Loadrunner一样对于多用户并发时,重复登入或者数据的重复使用会造成脚本的失败,那么我们引入Loadrunner的参数化概念,对用户数据进行参数化来使脚本运行成功. 头绪:   use ...

  7. 下载安装ngnix

    在这个网站上进行下载,http://nginx.org/en/download.html,由于我的是windows系统 我下载解压后,打开文件夹里面看到ngix.exe,我去双击它,发现它就是一闪,后 ...

  8. Spring @Resource,@Autowired,@Qualifier的注解注入和区别

    spring2.5提供了基于注解(Annotation-based)的配置,我们可以通过注解的方式来完成注入依赖.在Java代码中可以使用 @Resource或者@Autowired注解方式来经行注入 ...

  9. Netty权威指南(笔记一)

    转载:http://blog.csdn.net/clarkkentyang/article/details/52529785 第一章(略) 第二章 NIO入门 2.1传统的BIO编程(同步阻塞I/O服 ...

  10. LeetCode - Fruit Into Baskets

    In a row of trees, the i-th tree produces fruit with type tree[i]. You start at any tree of your cho ...