django3.0自定义文件存储系统
一、django与fdfs文件系统的交互图

二、实战部分,自定义文件存储系统是很多个app都可以用到,所以放到公共工具类中;django默认文件存储是在本地的media文件下存放,所以需要修改django文件存储行为
# 修改django的文件存储系统,使用fastdfs文件系统存储文件 DEFAULT_FILE_STORAGE = 'utils.fdfs.storage.FdfsStorage' # django服务器的client.conf文件的路径,该文件用于完成django服务器将文件存储在fdfs远程文件系统中 FDSF_CLIENT_CONF_PATH = os.path.abspath(os.path.join(BASE_DIR, 'utils', 'fdfs', 'client.conf')) # fdfs远程文件存储系统用nginx做负载均衡的nginx服务器地址与端口 FDSD_NGINX_BASE_PATH = 'http://192.168.52.133:9999/'
三、FdfsStorage类自定义了文件上传时的行为,如下
import os from django.core.files.storage import Storage from fdfs_client.client import get_tracker_conf, Fdfs_client from ECweb import settings class FdfsStorage(Storage): """ 自定义文件存储类 """ def __init__(self, fdfs_client_conf_path=None, fdfs_nginx_base_path=None): """初始化配置项 :param fdfs_client_conf_path:django服务器的client.conf文件的路径,该文件用于完成django服务器将文件存储在fdfs远程文件系统中 :param fdfs_nginx_base_path:fdfs远程文件存储系统用nginx做负载均衡的nginx服务器地址与端口 :return: """ self.client_conf = fdfs_client_conf_path if fdfs_client_conf_path else settings.FDSF_CLIENT_CONF_PATH self.nginx_base_path = fdfs_nginx_base_path if fdfs_nginx_base_path else settings.FDSD_NGINX_BASE_PATH def _open(self, name, mode='rb'): """打开文件时,django会自动执行这个方法 :argument name: :argument mode: :return: """ pass def _save(self, name, content): """ 文件被保存的时候django会自动执行 :param name: 带有模型类中设置的uoload_to的文件名,类似于kind\banner01.jpg,字符串形式 :param content: django.core.files.uploadedfile.InMemoryUploadedFile的一个实例,一个文件对象 :return: 返回fdfs文件系统存储成功后的文件名 """ client_conf = get_tracker_conf(conf_path=self.client_conf) remote_client = Fdfs_client(client_conf) #image_path = os.path.abspath(os.path.join(settings.BASE_DIR, 'static', 'images', content.name)) # 使用文件名上传文件 # result = remote_client.upload_by_filename(image_path) # result = remote_client.upload_appender_by_filename(image_path) # 使用缓冲池上传文件 result = remote_client.upload_appender_by_buffer(content.read()) if not ('successed' in result.get('Status')): raise NameError("文件保存失败") # 取出存储在fdfs系统上的文件名,该值是bytes,需要解码 remote_filename = result.get('Remote file_id').decode('utf-8') # 返回在fdfs文件系统上的文件名称 return remote_filename def url(self, name): """ 返回存储在fdfs文件系统上的文件名,django会自动调用 :param name: 这里的name等同于_save()的返回值 :return: 存储在fdfs文件系统上的文件名,这样http://192.168.52.133:9999/group1/M00/00/00/wKg0hV7vlH-ECkJZAAAAAF1TetM442.jpg """ return self.nginx_base_path + name def exists(self, name): """ 判断文件名是否可用。False表示可用,因为在fdfs系统中不存在重名 :param name: :return: """ return False
四、上传成功后,可以在本机创建一个test.html验证是否上传成功,使用谷歌浏览器打开html文件即可
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <img src="http://192.168.52.133:9999/group1/M00/00/00/wKg0hV7vqA2AAbI5AAAmv11TetM4242208"> </body> </html>
浙公网安备 33010602011771号