在Django中启动FastDFS遇到的一系列问题

问题描述

在python3.7版本中,导入fdfs_client模块失败

解决方案

移除所有已安装的fdfs模块,安装py3Fdfs模块from py3Fdfs.client import Fdfs_client即可,但是你以为这样就结束了?恭喜你现在正是入坑。因为版本更替的原因py3Fdfs中的函数名、用法表面上与fdfs_client中的一样,但是当你将项目跑起来会出现异常TypeError: type object argument after ** must be a mapping, not str。实际上如果仔细研究它们的源码后你会发现其实存在差异。在py3Fdfs中Fdfs_client传入的配置文件解析项trackers中host_tuple从早先的字符串修改为一个元组。fdfs_client()中的参数需要使用经过get_tracker_conf()函数的加工返回值。并且client.upload_by_buffer()的返回值更替为byte类型,返回值需要先经过解码成str类型,否则会报错

真正的解决方案

移除所有已安装的fdfs前缀的模块,安装py3Fdfs模块

from fdfs_client.client import Fdfs_client, get_tracker_conf
 def _save(self, name, content):
        client = Fdfs_client(get_tracker_conf(self.client_conf))
        res = client.upload_by_buffer(content.read())
        filename = res.get('Remote file_id')
        return filename.decode()

我所使用的fastFDFS自定义的storage类

settings.py中添加:

# 设置Django的文件存储类
DEFAULT_FILE_STORAGE = 'utils.fdfs.storage.FDFSStorage'

# 设置fdfs使用的client.conf文件路径
FDFS_CLIENT_CONF = os.path.join(BASE_DIR, './utils/fdfs/client.conf')

# 设置fdfs存储服务器上nginx的IP和端口号(默认8888)
FDFS_URL = 'http://192.168.243.129:8888/'

新建的存放自定义storage类的.py文件:

from django.conf import settings
from django.core.files.storage import Storage
from django.utils.deconstruct import deconstructible

from fdfs_client.client import Fdfs_client, get_tracker_conf

@deconstructible
class FDFSStorage(Storage):
    """自定义的fastdfs文件存储系统类"""

    def __init__(self, client_conf=None, base_url=None):
        """初始化"""
        if not client_conf:
            client_conf = settings.FDFS_CLIENT_CONF
        self.client_conf = client_conf

        if not base_url:
            base_url = settings.FDFS_URL
        self.base_url = base_url

    def _open(self):
        """打开文件"""
        pass

    def _save(self, name, content):
        """保存文件"""
        client = Fdfs_client(get_tracker_conf(self.client_conf))

        res = client.upload_by_buffer(content.read())

        if res.get('Status') != 'Upload successed.':
            # 上传失败
            raise Exception('上传文件到fast dfs失败')

        # 获取返回的文件ID
        filename = res.get('Remote file_id')
        return filename.decode()

    def exists(self, name):
        '''在save()函数之前执行,Django判断文件名是否可用
        返回True如果给定的名称引用的文件在存储系统中已经存在,或者False如果名称是适用于一个新的文件。
        本项目文件并非存放在django中,即返回一定为False'''
        return False

    def url(self, name):
        '''返回访问文件的url路径'''
        return self.base_url + name

从网上下载的client.conf文件中只需要修改:

# the base path to store log files 配置存放日志文件的路径
base_path=F:\project\log
#  "host:port", host can be hostname or ip address
#配置tracker_server IP地址,端口号port默认22122
tracker_server=192.168.243.129:22122

你可能感兴趣的:(fastdfs)