ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

django 自定义fdfs文件存储类

2021-12-22 18:34:50  阅读:130  来源: 互联网

标签:name 自定义 self django content file path fdfs os


FdfsStorage.py
# -*- coding: utf-8 -*-
import logging
from django.conf import settings
from django.core.files.storage import FileSystemStorage
from fdfs_client.client import Fdfs_client, get_tracker_conf


logger = logging.getLogger('django')


class FdfsStorage(FileSystemStorage):

    def url(self, name):
        """
        全路径
        :param name:
        :return:
        """
        return settings.__getattr__('CUSTOM_STORAGE_BASE_URL') + name

    def save(self, name, content, max_length=None):
        # 现在修好了 直接跳掉原来的保存过程 返回个新name就行 2021.12.10 17:57
        conf = get_tracker_conf(f'{settings.BASE_DIR}/utils/fastdfs/client.conf')
        client = Fdfs_client(conf)
        # res = client.upload_by_buffer(filebuffer=content.file.read())
        res = client.upload_by_buffer(filebuffer=content.file.read(), file_ext_name=name.split('.')[-1])

        new_name = res['Remote file_id'].decode()
        logger.info(f'上传文件至fdfs {res} name:{name} new_name: {new_name}')
        return str(new_name).replace('\\', '/')

  

settings.py 路径随便 找得着就行

UBUNTU1 = '192.168.204.128'

CUSTOM_STORAGE_BASE_URL = f'http://{UBUNTU1}:8888/'  # fdfs

DEFAULT_FILE_STORAGE = 'utils.fastdfs.fdfs_storage.FdfsStorage'

  

 

作为参考 默认的save方法源码如下

def save(self, name, content, max_length=None):
        """
        Save new content to the file specified by name. The content should be
        a proper File object or any Python file-like object, ready to be read
        from the beginning.
        """
        # Get the proper name for the file, as it will actually be saved.
        if name is None:
            name = content.name

        if not hasattr(content, 'chunks'):
            content = File(content, name)

        name = self.get_available_name(name, max_length=max_length)
        return self._save(name, content)

  

def _save(self, name, content):
    full_path = self.path(name)

    # Create any intermediate directories that do not exist.
    directory = os.path.dirname(full_path)
    try:
        if self.directory_permissions_mode is not None:
            # Set the umask because os.makedirs() doesn't apply the "mode"
            # argument to intermediate-level directories.
            old_umask = os.umask(0o777 & ~self.directory_permissions_mode)
            try:
                os.makedirs(directory, self.directory_permissions_mode, exist_ok=True)
            finally:
                os.umask(old_umask)
        else:
            os.makedirs(directory, exist_ok=True)
    except FileExistsError:
        raise FileExistsError('%s exists and is not a directory.' % directory)

    # There's a potential race condition between get_available_name and
    # saving the file; it's possible that two threads might return the
    # same name, at which point all sorts of fun happens. So we need to
    # try to create the file, but if it already exists we have to go back
    # to get_available_name() and try again.

    while True:
        try:
            # This file has a file path that we can move.
            if hasattr(content, 'temporary_file_path'):
                file_move_safe(content.temporary_file_path(), full_path)

            # This is a normal uploadedfile that we can stream.
            else:
                # The current umask value is masked out by os.open!
                fd = os.open(full_path, self.OS_OPEN_FLAGS, 0o666)
                _file = None
                try:
                    locks.lock(fd, locks.LOCK_EX)
                    for chunk in content.chunks():
                        if _file is None:
                            mode = 'wb' if isinstance(chunk, bytes) else 'wt'
                            _file = os.fdopen(fd, mode)
                        _file.write(chunk)
                finally:
                    locks.unlock(fd)
                    if _file is not None:
                        _file.close()
                    else:
                        os.close(fd)
        except FileExistsError:
            # A new name is needed if the file exists.
            name = self.get_available_name(name)
            full_path = self.path(name)
        else:
            # OK, the file save worked. Break out of the loop.
            break

    if self.file_permissions_mode is not None:
        os.chmod(full_path, self.file_permissions_mode)

    # Store filenames with forward slashes, even on Windows.
    return str(name).replace('\\', '/')

  

可以看出 默认的save明显复杂得多 实现了同名/权限等诸多校验

借助Fdfs_client 存储过程用不着自己实现(都在upload_by_buffer里是吧)

标签:name,自定义,self,django,content,file,path,fdfs,os
来源: https://www.cnblogs.com/ietar/p/15720666.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有