天天看點

Django自定義檔案存儲類

Django自定義檔案存儲類

環境準備

https://blog.csdn.net/weixin_44834666/article/details/105701632

配置檔案準備 建立一個client.conf檔案 寫入下面的代碼

# connect timeout in seconds
# default value is 30s
connect_timeout=10

# network timeout in seconds
# default value is 30s
network_timeout=60

# the base path to store log files
base_path=/home/fish/storelog

# tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
tracker_server=192.168.198.136:22122

#standard log level as syslog, case insensitive, value list:
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=info

# if use connection pool
# default value is false
# since V4.05
use_connection_pool = false

# connections whose the idle time exceeds this time will be closed
# unit: second
# default value is 3600
# since V4.05
connection_pool_max_idle_time = 3600

# if load FastDFS parameters from tracker server
# since V4.05
# default value is false
load_fdfs_parameters_from_tracker=false

# if use storage ID instead of IP address
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# default value is false
# since V4.05
use_storage_id = false

# specify storage ids filename, can use relative or absolute path
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# since V4.05
storage_ids_filename = storage_ids.conf


#HTTP settings
http.tracker_server_port=80

#use "#include" directive to include HTTP other settiongs
##include http.conf

           

在項目目錄下建立一個fdfs包,将上面的配置檔案放到包中,并建立一個storage.py檔案,寫入下面代碼

from django.core.files.storage import Storage # 導入檔案存儲類的父類
from fdfs_client.client import Fdfs_client, get_tracker_conf
from django.conf import settings
# 繼承Storage
class FDFSStorage(Storage):
    """ fastdfs 檔案存儲類 """
    # 繼承Storage必須實作_open()和_save()方法
    def __init__(self, client_conf=None, base_url=None):
        """初始化"""
        if client_conf is None:
            # client_conf = './apps/utils/fdfs/client.conf'
            client_conf = settings.FDFS_CLIENT_CONF
        self.client_conf = client_conf

        if base_url is None:
            base_url = settings.FDFS_URL
        self.base_url = base_url


    # _open 用來讀取檔案
    def _open(self, name, mode='rb'):
        """ 打開檔案時使用 """
        pass

    # _save 用來儲存檔案,name 上傳檔案的名字  content 是file類的一個對象,包含上傳檔案内容, 可以用read()
    def _save(self, name, content):
        """ 儲存檔案時使用 """

        # 建立一個Fdfs_client對象
        client = Fdfs_client(get_tracker_conf(self.client_conf))

        # 上傳檔案到storage伺服器, 通過檔案内容上傳,傳回一個字典
        # dict
        # {
        #     'Group name': group_name,
        #     'Remote file_id': remote_file_id,
        #     'Status': 'Upload successed.',
        #     'Local file name': '',
        #     'Uploaded size': upload_size,
        #     'Storage IP': storage_ip
        # }
        ret = client.upload_by_buffer(content.read())

        # 判斷是否上傳成功
        if ret.get('Status') != 'Upload successed.':
            # 失敗則抛出異常
            raise Exception('上傳檔案到fast dfs失敗')

        # 如果上傳成功,就擷取檔案ID
        filename = ret.get('Remote file_id')

        # 傳回檔案ID
        return filename.decode()

    # 重寫exists方法
    # 判斷上傳的檔案名是否可用
    def exists(self, name):
        return False


    # 通過url通路檔案
    def url(self, name):
        """ 通路檔案的url路徑 """
        # name 儲存的是檔案ID
        return self.base_url+name
           

需要注意的點

  1. _save 裡 字典取出來的是位元組流類型的資料,return 的時候要使用decode方法進行轉換
  2. 繼承Storage必須實作_open()和_save()方法
  3. url方法 用來通路檔案
  4. exists方法用來判斷檔案名是否重複,但因為我們不存放在Django目錄中,是以一直都是False

在Django 中settings檔案配置三個變量

# 指定Django使用的檔案存儲類 ,上面編寫的py檔案的路徑
DEFAULT_FILE_STORAGE = 'utils.fdfs.storage.FDFSStorage'
# 設定fdfs使用的client.conf檔案路徑 ,變量名自己取,與上面的py檔案一緻
FDFS_CLIENT_CONF = './apps/utils/fdfs/client.conf'
# 設定fdfs存儲伺服器ngibx的ip和端口号,變量名自己取,與上面的py檔案一緻
FDFS_URL = 'http://192.168.198.136:8888/'
           

繼續閱讀