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
需要注意的點
- _save 裡 字典取出來的是位元組流類型的資料,return 的時候要使用decode方法進行轉換
- 繼承Storage必須實作_open()和_save()方法
- url方法 用來通路檔案
- 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/'