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>

 

posted @ 2020-06-21 19:08  vevian  阅读(16)  评论(0)    收藏  举报