Django 的文件存储

来源:互联网 发布:it服务是什么 编辑:程序博客网 时间:2024/05/22 01:48

起因

由于老师项目的需要,要在服务器端存储生成的文件,用Python的File虽然能够实现,但是Django这么大的框架肯定支持文件存储的,所以我认真读了一下官方文档,把所得记下来。

相关链接

Django官方文档Stroage API
该Blog是基于官方文档和实践的记录,如有不对的地方请不吝赐教。

相关内容

Storage 类

  Storage类提供了文件存储的标准化API,所有的默认操作都可以被继承的重写,Django提供的默认的FileSystemStorage 类也继承了Storage,如果想要定义的文件存储类(也叫存储系统),可以继承Stroage类并且重写相应的操作

Storage类定义的重要的API
  • accessed_time(name):返回上一次访问该文件的datetime。如果无法获取该文件的最近一次访问的时间,将会抛出一个NotImplementedError异常。

  • create_time(name):返回创建该文件的时间,若无法获取则抛出NotImplementedError异常。

  • delete(name):删除对应名称的文件的,若存储系统不支持delete操作将会抛出NotImplementedError
    异常。

  • exists(name):返回指定名称的文件是否存在了存储系统中的Boolean值

  • get_available_name(name, max_length=None):返回一个基于name参数的可以存入制定存储系统的名称,如果指定了max_length参数,返回的文件名的最大长度将不会超过该长度,如果没有找到唯一可用的文件存储名称,将会抛出一个SuspiciousFileOperation错误,如果name文件名存在,将在name后加下划线和随机的7个字符返回。(这个搞不是很懂,应该是防止文件名重复而在重复的name后加上一个随机串)

  • open(name, mode='rb'):打开name指定名称的文件。

  • path(name):返回一个Python标准库open()能够打开的文件路径, 对于不能够访问本地文件的存储系统,将会抛出一个NotImplementedError错误

  • save(name, content, max_length=None):通过当前存储系统使用指定的名称保存文件,如果存在了和name参数制定的同名文件,存储系统将会把name修改为唯一的名称(实际是调用get_available_name方法),并且文件保存成功后返回该文件名。content参数必须是django.core.files.FileFile子类的实例。


FileSystemStorage 类

FileSystemStorage类实现了存储文件到本地文件系统的基本api,它继承并实现了Storage的所有公共接口,类定义如下:

class FileSystemStorage(location=None,                        base_url=None,                        file_permissions_mode=None,                        directory_permissions_mode=None)
  • location:存储文件的绝对路径,默认是MEDIA_ROOT设置的路径

  • base_url:能够获得存储在该路径的文件的URL,默认为MEDIA_URL的设置。

  • file_permissions_mode:文件存储时获得的文件存储系统的权限,默认是FILE_UPLOAD_PERMISSIONS(644)

  • directory_permissions_mode:文件存储时文件夹获得的文件系统权限。


两种方法来获取当前的存储类

Django 提供了两种方法来获取当前的默认的存储的类。

class DefaultStorage

在DefaultStorage中内部使用了get_storage_class()方法。创建一个DefaultStorage对象,返回配置文件DEFAULT_FILE_STORAGE中制定的的存储的系统。

样例:

from django.core.files.storage import DefaultStorage# defaultStorage 是settings文件中指定的存储类defaultStorage = DefaultStorage() 

class DefaultStorage的源代码

class DefaultStorage(LazyObject):    def _setup(self):        # 这里调用了get_storage_class()方法得到其对应的类并创建了一个对象        self._wrapped = get_storage_class()()

get_storage_class(import_path=None)

该方法返回一个类(类型而不是对象)或者一个实现了storage API的模块

参数import_path为None时,返回settings文件DEFAULT_FILE_STORAGE中指定的类型,若提供类此参数,get_storage_class将会试图从提供的路径中import相应的class或者module并将对应的类型返回,若找不到相应的类型则会抛出一个错误。

样例:

from django.core.files.storage import get_storage_class# theStorageClass只是一个默认指定的一个类型而不是一个对象theStorageClass = get_storage_class()# theStorage 是一个默认指定的存储类的一个对象theStorage = get_storage_class()()

get_storage_class的源代码

def get_storage_class(import_path=None):    return import_string(import_path or settings.DEFAULT_FILE_STORAGE)

Attentation: 默认的settings文件中没有关于DEFAULT_FILE_STORAGE的配置,这时默认设置是django.core.files.storage.FileSystemStorage

实际栗子

例如有个需求是讲新建一个Hello.md文件并”# Hello world!”写入该文件中。可以这么写

from django.core.files.base import ContentFilefrom django.core.files.storage import get_storage_classstorageSystem = get_storage_class()('/Absolute/path/to/save/file')the_file = ContentFile(content="#Hello world!",name="Hello.md")storageSystem.save(content=the_file)

这里的get_storage_class使用了setting文件中默认的类即FileSystemStorage 类

新手学Django,可能有所疏漏,恳请指出。

0 0