【Django】使用FastDFS docker镜像存储图片和读取图片_docker本地知识库读取的图片-程序员宅基地

技术标签: django  Django  DRF  fastdfs  mysql  docker  

1.FastDFS

FastDFS是一个用C语言写的开源的轻量级分布式文件系统

功能包括文件存储、文件访问(文件上传、文件下载)、文件同步等,解决了大容量存储和负载均衡的问题,特别适合以文件为载体的在线服务,如相册网站、视频网站

FastDFS架构 包括Client、Tracker server和Storage server

我们在Django项目存储和读取图片可以通过FastDFS实现,但这里使用docker运行该镜像

2.docker运行FastDFS
2.1 安装FastDFS

先在系统上安装好Docker,然后从仓库获取FastDFS镜像

sudo docker image pull delron/fastdfs
2.2 开启tracker

将 tracker 运行目录映射到宿主机的 /var/fdfs/tracker目录中

sudo rm -rf /var/fdfs/*
sudo mkdir /var/fdfs/tracker
sudo docker container rm -f tracker
sudo docker run -dit --name tracker --network=host -v /var/fdfs/tracker:/var/fdfs delron/fastdfs tracker
2.3 开启storage

将 storage 运行目录映射到宿主机的 /var/fdfs/storage目录中

sudo mkdir /var/fdfs/storage
sudo docker container rm -f storage
sudo docker run -dti --name storage --network=host -e TRACKER_SERVER=192.168.203.153:22122 -v /var/fdfs/storage:/var/fdfs delron/fastdfs storage

注意:如果遇到无法从重启storage容器的情况,可以删除/var/fdfs/storage/data目录下的fdfs_storaged.pid 文件,然后重新运行storage

3.自定义Django存储后端
3.1 fastdfs.py

在项目中新建 meiduo_mall/utils/fastdfs/fastdfs.py 文件

from django.core.files.storage import Storage
from django.conf import settings

class FastDFSStorage(Storage):
    def _open(self, name, mode='rb'):
        # 打开django本地文件
        pass

    def _save(self, name, image_obj, max_length=None):
    	# 规则1:SKUImage(sku=<SKU对象>, image=<文件对象>) ---> image赋值为一个文件对象的话,会触发文件存储后端来完成;
		# 规则2:SKUImage(sku=<SKU对象>, image="图片标示,图片id") ---> image赋值为一个字符串,那么就不会触发文件存储后端,直接将该字符串存入mysql;
        # 如果SKUImage(image=<文件对象>) --> 当前存储后端的_save方法,完成图片的保存动作
        # 此处我们需要把文件保存到fdfs(上传到fdfs)
        # name: 文件名称,同时也是保存到Django本地的文件名称 ---> 无需使用
        # image_obj: 传来的文件对象 --> 就是ImageField字段在新建或者更新的时候被赋值的文件对象

        conn = Fdfs_client('./meiduo_mall/settings/client.conf') # 使用配置文件
        res = conn.upload_by_buffer(image_obj.read())
        if res is None:
            raise serializers.ValidationError('上传fdfs失败!')
        file_id = res['Remote file_id']

        # 注意:_save方法返回值就是当前字段,存储在mysql中的文件id
        return file_id

    def exists(self, name):
        # 功能:判断上传的文件在Django本地是否重复
        # True:表示重复
        # Fales:表示不重复
        return False

    def url(self, name):
        """
        # 默认只返回文件标识,我们在返回前加上协议域名等前缀构成完整URL
        # return "http://image.meiduo.site:8888/" + name
        return settings.FDFS_BASE_URL + name
3.2 client.conf

FastDFS配置文件,/meiduo_mall/settings/client.conf

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

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

# the base path to store log files
base_path=/Users/weiwei/Desktop/01-fdfs客户端的使用demo/logs

# 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.203.153: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

3.3 settings.py

修改dev配置文件

# 指定自定义的Django文件存储类
DEFAULT_FILE_STORAGE = 'meiduo_mall.utils.fastdfs.FastDFSStorage'
# 定义fdfs服务url前缀
FDFS_BASE_URL = 'http://image.meiduo.site:8888/'
4.存储图片

方法1,在ModelViewSet视图集存储

class ImageView(ModelViewSet):
    serializer_class = ImageSeriazlier
    queryset = SKUImage.objects.all()
    pagination_class = PageNum
	
	...
	
    # 重写拓展类的保存业务逻辑
    def create(self, request, *args, **kwargs):
          # 创建FastDFS连接对象
        client = Fdfs_client(settings.FASTDFS_PATH)
        # 获取前端传递的image文件
        data = request.FILES.get('image')
        # 上传图片到fastDFS
        res = client.upload_by_buffer(data.read())
        # 判断是否上传成功
        if res['Status'] != 'Upload successed.':
            return Response(status=403)
        # 获取上传后的路径
        image_url = res['Remote file_id']
        # 获取sku_id
        sku_id = request.data.get('sku')[0]
        # 保存图片
        img = SKUImage.objects.create(sku_id=sku_id, image=image_url)
                # 返回结果
        return Response(
            {
    
                'id': img.id,
                'sku': sku_id,
                'image': img.image.url
            },
            status=201  # 前端需要接受201状态
        )

方法2,在ModelSerializer序列化器存储

class ImageModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = SKUImage
        fields = ['id','sku','image']
    
    # 规则1:SKUImage(sku=<SKU对象>, image=<文件对象>) ---> image赋值为一个文件对象的话,会触发文件存储后端来完成;
    # 规则2:SKUImage(sku=<SKU对象>, image="图片标示,图片id") ---> image赋值为一个字符串,那么就不会触发文件存储后端,直接将该字符串存入mysql;
    def validate(self, attrs):
        image_obj = attrs.get('image')
        conn = Fdfs_client('./meiduo_mall/settings/client.conf')
        res = conn.upload_by_buffer(image_obj.read())
        if res is None:
            raise serializers.ValidationError('fdfs上传失败')
        attrs['image'] = res['Remote file_id']
        return attrs
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_39147299/article/details/108874819

智能推荐

linux查看进程状态_linux 查询 进程 状态-程序员宅基地

文章浏览阅读7.1k次。ps命令是查看进程状态的基础指令,有以下几个常用参数:一:最常用的参数组合及解析\1. 如果想查看包含其他使用者的进程,和PID,CPU占有率,记忆体使用情况,运行状态等,可以输入ps -aux USER:进程拥有者,示例中是root。PID:进程ID,用户ID为UID,父进程ID为PPID%CPU:占用的CPU使用率,ID号为1的进程为0%MEM:占用的物理内存百分比,ID号为1的进程为0VSZ:占用的虚拟内存量,ID号为1的进程为194184RSS:占用的固定的内存量,ID号为1的进._linux 查询 进程 状态

aws EC2相关内容_aws ec2 ext4-程序员宅基地

文章浏览阅读472次。通过UserData在根目录创建文件夹:在Web服务器挂载两个磁盘一个10G系统 盘,一个10G数据盘(挂载点/goclouds), 并配置fstab做重启自动挂磁盘:(参考aws官方文档:https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/ebs-using-volumes.html)使用以下命令在您在上一步中..._aws ec2 ext4

pixhawk接口图以及引脚说明_pixhawk2.4.8飞控接线图-程序员宅基地

文章浏览阅读2.8w次,点赞13次,收藏196次。pixhawk接口图和引脚如下。pixhawk可以同时使用2个GPS,这只能使用其中一个罗盘,实际中飞控挑选其中信号好的一个GPS进行定位。硬件部分:第二个GPS插在serial 4/5接口上,线序与GPS口一致(参考GPS接口和serial 4/5接口)。软件部分:固件为apm3.2以上,然后到地面站”所有参数“中修改GPS_AUTO_STITCH参数值为1 以及修改GPS_TYPE2参..._pixhawk2.4.8飞控接线图

MATLAB中,使用load函数报错(ASCII 文件“XXX”的行号 1 中的文本未知 "�唷��"。)_ascii 文件 c:\users\17605\desktop\data.xls 的行号 1 中的文-程序员宅基地

文章浏览阅读1.9w次,点赞14次,收藏15次。1、本来想使用load函数在MATLAB导入Excel表格;2、使用load之后,出现了错误:ASCII 文件“XXX”的行号 1 中的文本未知 "�唷��";3、解决办法: 使用importdata函数代替load函数,则不会出错。..._ascii 文件 c:\users\17605\desktop\data.xls 的行号 1 中的文本未知

指定mysql的max_allowed_packet大小 -程序员宅基地

文章浏览阅读96次。max-allowed-packet  max_allowed_packet  Mysql 5.1 遇到的信息包过大问题 用客户端导入数据的时候,遇到 错误代码: 1153 - Got a packet bigger than 'max_allowed_packet' bytes 终止了数据导入。  当MySQL客户端或mysqld服务器收到大于max_allowed_packet字节..._mysqldump的时候 指定本次导出的max-allow-packet的大小

学习C语言你是否思考过表达式11111*11111的值是多少?把5个1换成6个1呢?9个1呢?...-程序员宅基地

文章浏览阅读500次。  学习C语言你是否思考过表达式11111*11111的值是多少?把5个1换成6个1呢?9个1呢?请看到这还不理解我想说什么的朋友自行编写代码实现一下,就会有特别深刻的印象了。解决方案:编写程序模拟笔算,按一位运算规则得出结果。#include<stdio.h>#include<math.h>void main(){   int i=0;   int n;..._学习c语言你是否思考过表达式11111*11111的值是多少?把5个1换成6个1呢?9个1呢

随便推点

STM8停产,新唐的N76E003 pin对pin替换STM8S003F3P6_stm8s003 pin对pin 代替-程序员宅基地

文章浏览阅读3.9k次。版权声明:本文为CSDN博主「qlexcel」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qlexcel/article/details/81069808随着STM8的停产,新唐的N76E003 pin对pin替换STM8S003F3P6,而且很便宜,故这个时候拿来替换使用再好不过。下面..._stm8s003 pin对pin 代替

【测试用例】测试用例设计方法论之KYM、MFQ、PPDS_kym模板-程序员宅基地

文章浏览阅读4.7k次,点赞15次,收藏24次。目 录一KYM:Know Your Mission1.1 用户维度1.2 产品维度1.3任务维度二 MFQ2.1单一功能(PPDS)2.2 功能交互2.3 质量属性一KYM:Know Your MissionKYM是Kown Your Mission的简称,顾名思义,就是帮助用例设计人员梳理测试任务的过程,它是一种系统的收集和整理测试启发的框架。在接触一些新事物或者面对一些新问题时,人们往往更关注与问题本身,也就是what,而忽略了问题产生的原因(why)和..._kym模板

【精通内核】CPU控制并发原理CPU中断控制内核解析_cpu 并发控制-程序员宅基地

文章浏览阅读1.8w次,点赞94次,收藏161次。本文讲解CPU角度的中断控制,CPU层面并行并发和中断控制的原理,现代CPU的缓存结构和架构图、CPU缓存一致性的源码原理,以及CPU如何通过编译器的屏障与指令实现系统屏障,经过内联汇编代码验证之后,证明上述所说的 Linux 内核用 volatile 关键字实现系统屏障(指令重排),加深对系统屏障的内核源码和原理的理解_cpu 并发控制

金融数据分析之pdfplumber提取年报PDF关键数据(其他PDF数据通用)_读取年报pdf中的固定资产数据-程序员宅基地

文章浏览阅读3.9k次,点赞10次,收藏68次。目录一、前言二、难点三、提取难点解决思路四、源代码一、前言小编最近遇到需求了:<1>从PDF提取出关键数据;<2>将关键数据整理到对应的Excel文件;<3>要求批处理,可以处理多个类似的内容的PDF文件;<4>重点还是提取上市公司年报的财务数据。小编看到这个需求,首先想到用python,应了那句“人生苦短,必须python”。是的,python确实是一门好用的工具语言。问问度娘,还真有用于处理PDF文件的Packa_读取年报pdf中的固定资产数据

[王垠系列]谈 Linux,Windows 和 Mac_c++优化 windows linux mac-程序员宅基地

文章浏览阅读676次。谈 Linux,Windows 和 Mac这段时间受到很多人的来信。他们看了我很早以前写的推崇 Linux 的文章,想知道如何“抛弃 Windows,学习 Linux”。天知道他们在哪里找到那么老的文章,真是好事不出门…… 我觉得我有责任消除我以前的文章对人的误导,洗清我这个“Linux 狂热分子”的恶名。我觉得我已经写过一些澄清的文章了,可是怎么还是有人来信问 Linux 的问题。也许因_c++优化 windows linux mac

仅供娱乐: 用中文命名,让汉字走向程序开发中!-程序员宅基地

文章浏览阅读783次。作者:荣泽威,杜宏林欢迎传播,请尊重版权,转贴请保证文章完整。最近在偶然的机会中和朋友发现php的命名规则为[a-zA-Z_/x7f-/xff][a-zA-Z0-9_/x7f-/xff]*就是说a到z,和A到Z,和_,和0x7f到0xff的字符都受到命名规则的支持,就是说,在php程序中,可以直接使用大部分汉字进行实际命名!经过测试发现,这样的惊讶让我们直达当今正逍遥的DotNet技术_中文命名

推荐文章

热门文章

相关标签