Django项目实战——12—(Docker和FastDFS上传和下载文件、浏览器下载并渲染图片(nginx)、录入商品数据和图片数据、首页广告)
1、Docker和FastDFS上传和下载文件
Docker安装运行FastDFS
获取FastDFS镜像
# 从仓库拉取镜像
sudo docker image pull delron/fastdfs# 解压资料中本地镜像
sudo docker load -i 文件路径/fastdfs_docker.tar
开启tracker
容器
- 我们将
tracker
运行目录映射到宿主机的/var/fdfs/tracker
目录中。
sudo docker run -dit --name tracker --network=host -v /var/fdfs/tracker:/var/fdfs delron/fastdfs tracker
开启storage
容器
TRACKER_SERVER=Tracker
的ip地址:22122
(Tracker
的ip地址不要使用127.0.0.1
)- 我们将
storage
运行目录映射到宿主机的/var/fdfs/storage
目录中。
sudo docker run -dti --name storage --network=host -e TRACKER_SERVER=192.168.232.140:22122 -v /var/fdfs/storage:/var/fdfs delron/fastdfs storage
查看已经启动的storage和tracker
注意:如果无法重启storage
容器,可以删除/var/fdfs/storage/data
目录下的fdfs_storaged.pid
文件,然后重新运行storage
。
FastDFS客户端上传文件
Python版本的FastDFS
客户端使用参考文档:https://github.com/JaceHo/fdfs_client-py
- 安装
FastDFS
客户端扩展
• 安装准备好的fdfs_client-py-master.zip
到虚拟环境中
pip install fdfs_client-py-master.zip
pip install mutagen
pip install requests
从 Python版本的FastDFS
客户端使用参考文档:https://github.com/JaceHo/fdfs_client-py
中下载fdfs_client-py-master.zip
文件,安装到项目的虚拟环境中:
Windows的Python环境引入fdfs_client-py包遇到的问题
https://blog.csdn.net/mingyuli/article/details/104171195
如果安装不成功,请参考:
Windows的Python环境引入fdfs_client-py包遇到的问题
https://blog.csdn.net/mingyuli/article/details/104171195
解决方法:
Fastdfs
客户端ModuleNotFoundError: No module named 'mutagen._compat'
问题
https://www.cnblogs.com/sewen-H/p/13362598.html
- 准备FastDFS客户端扩展的配置文件
•shop.utils.fastdfs.client.conf
FastDFS客户端扩展的配置文件:shop/utils/fastdfs/client.conf
"""
FastDFS客户端扩展的配置文件:shop/utils/fastdfs/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=E:\ENV\Django_project_shop\shop\static\images # 本机路径# 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.232.140:22122 # 改为虚拟机ip#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
注意:上面代码中需要修改的内容为
base_path=FastDFS客户端存放日志文件的目录
tracker_server=运行Tracker服务的机器ip:22122
- FastDFS客户端实现文件存储
# 使用 shell 进入 Python交互环境
python manage.py shell
# 1. 导入FastDFS客户端扩展
from fdfs_client.client import Fdfs_client# 2. 创建FastDFS客户端实例 注意:windows环境下绝对路径会发生转义,需要加上 "r" 说明是原生字符串
client = Fdfs_client(r'绝对路径:shop/utils/fastdfs/client.conf')# 3. 调用FastDFS客户端上传文件方法
ret = client.upload_by_filename('/kk.jpeg')
在创建FastDFS客户端实例
client = Fdfs_client(r'shop/utils/fastdfs/client.conf')
过程中,可能会出现:
UnicodeDecodeError: 'gbk' codec can't decode byte 0xaf in position 19: illegal multibyte sequence
的错误,
解决方案是:重新安装fdfs_client-py-master.zip
文件,并修改其中的代码文件
创建FastDFS客户端实例出现报错:Source contains parsing errors: [line 2]: '"""\n' [line 4]: '"""\n'
或者unicodeescape’ codec can’t decode bytes in position XXX: trun
解决方案为:
上传文件ret = client.upload_by_filename(r’E:/1.jpg’)
报错:Error: 10061 connect to 192.168.xxx,由于目标计算机积极拒绝,无法连接
解决方案:https://blog.csdn.net/CaoMei_HuaCha/article/details/80865444
上传文件fdfs_client.exceptions.DataError: [-] Error: 2, No such file or directory报错问题
:
解决方案:https://blog.csdn.net/weixin_45336184/article/details/104289171
最终上传成功
虚拟机服务器查看文件:
2、浏览器下载并渲染图片(nginx)
- 协议: http
- IP地址:192.168.232.140 (虚拟机服务器ip) Nginx服务器的IP地址
- 因为 FastDFS 擅长存储静态文件,但是不擅长提供静态文件的下载服务,所以我们一般会将 Nginx 服务器绑定到 Storage ,提升下载性能。
- 端口:8888 -------Nginx服务器的端口。
- 路径:
group1/M00/00/00/wKjojF9Q3pOAeBzvAAAN4yGVxhg331.png
• 文件在Storage上的文件索引。 - 完整图片下载地址
•http://192.168.232.140:8888/group1/M00/00/00/wKjojF9Q3pOAeBzvAAAN4yGVxhg331.png
Nginx安装
sudo apt install nginx
编写测试代码:shop.utils.fdfs_t.html
<img src="http://192.168.232.140:8888/group1/M00/00/00/wKjojF9Q3pOAeBzvAAAN4yGVxhg331.png" width="320" height="480">
安装nginx
虚拟机服务器
Win10中查看上传文件
成功查看上传的文件
3、录入商品数据和图片数据
SQL脚本录入商品数据
mysql -h127.0.0.1 -uroot -pmysql lgshop < 文件路径/goods_data.sql
FastDFS服务器录入图片数据
准备新的图片数据压缩包
删除 Storage 中旧的data目录
3. 拷贝新的图片数据压缩包到 Storage,并解压
# 解压命令
sudo tar -zxvf data.tar.gz
4. 查看新的data目录
4、首页广告
展示首页商品频道分类
分析首页商品频道分类数据结构
查询首页商品频道分类
首页广告视图文件apps/contents/views.py
"""
首页广告视图文件
apps/contents/views.py
"""
from django.shortcuts import render
from django.views import View
from django.http import HttpResponse
from collections import OrderedDict # 有序的字典,不同于普通字典
from goods.models import GoodsChannel,GoodsCategory # 商品频道,商品类别class IndexView(View):"""首页广告界面"""def get(self, request):"""提供首页界面"""# 查看并展示商品的分类categories = {}# 查询所有的商品频道# channels = GoodsChannel.objects.all()# 37个一级类别channels = GoodsChannel.objects.order_by('group_id', 'sequence') # 根据group_id排序,再根据组内顺序sequence排序# 遍历所有频道for channel in channels:group_id = channel.group_idif group_id not in categories: # category最顶级商品类别,如果当前频道不在顶级商品类别中categories[group_id] = {'channel': [], "sub_cats": []} # 创建需要传输的数据格式# 当前频道对应的一级类别cat1 = channel.category # cat1是对象,category是外键字段categories[group_id]['channel'].append({ # channel本身包含字典数据"id": cat1.id,"name": cat1.name, # category外键关联的name字段"url": channel.url})# 查询二级和三级类别信息for cat2 in GoodsCategory.objects.filter(parent__id=cat1.id).all(): # 通过频道对应的一级类别来查询cat2.sub_cats = [] # 创建是为了方便cat3进行添加数据categories[group_id]['sub_cats'].append({"id": cat2.id,"name": cat2.name, # cat2对象本身模型GoodsCategory的name字段"sub_cats": cat2.sub_cats})# 查询三级类别信息for cat3 in GoodsCategory.objects.filter(parent__id=cat2.id).all(): # 通过二级类别来查询三级cat2.sub_cats.append({ # 方便cat3进行添加数据到cat2的list中"id": cat3.id,"name": cat3.name,})# categories[group_id]['sub_cats'][].append({ # 这种方法添加数据,sub_cats数据无法添加# "id": cat3.id,# "name": cat3.name,# })context = {"categories": categories, # 整体拼接后的数据}return render(request, "index.html", context=context)"""需要形成如下的数据格式并传输给前端页面进行渲染
{"1":{# 频道"channels":[{"id":1, "name":"手机", "url":"http://shouji.jd.com/"},{"id":2, "name":"相机", "url":"http://www.baidu.cn/"}],# 二级标签"sub_cats":[{"id":38,"name":"手机通讯","sub_cats":[{"id":115, "name":"手机"},{"id":116, "name":"游戏手机"}]},{"id":39,"name":"手机配件",# 三级标签"sub_cats":[{"id":119, "name":"手机壳"},{"id":120, "name":"贴膜"}]}]},"2":{"channels":[],"sub_cats":[]}
}
"""
渲染首页商品频道分类
首页界面:templates/index.html
{# apps/contents/views.py文件中传递的categories数据进行渲染 #}<ul class="sub_menu">{# 一级查询 #}{% for group in categories.values %}<li><div class="level1">{% for channel in group.channels %}<a href="{{ channel.url }}">{{ channel.name }}</a>{% endfor %}</div><div class="level2">{# 二级查询 #}{% for cat2 in group.sub_cats %}<div class="list_group"><div class="group_name fl">{{ cat2.name }} ></div><div class="group_detail fl">{# 三级查询 #}{% for cat3 in cat2.sub_cats %}<a href="/list/{{ cat3.id }}/1/">{{ cat3.name }}</a>{% endfor %}</div></div>{% endfor %}</div></li>{% endfor %}</ul>
展示首页商品广告
{ # 传输数据格式如下所示"index_lbt":[{"id":1, "category": 1,"title": '美图',"url": 'http://www.baidu.com',"image": "group/M00/00/01/ADASDADA-CZXCSAasdsadada","text": "","sequence": 1,"status": 1},{"id":2, "category": 1,"title": '黑色星期五',"url": 'http://www.baidu.com',"image": "group/M00/00/01/ADASDADA-CZXCSAasdsadada","text": "","sequence": 2,"status": 1}],"index_kx":[{"id":5, "category": 2,"title": 'i7顽石低至3999',"url": 'http://www.baidu.com',"image": "group/M00/00/01/ADASDADA-CZXCSAasdsadada","text": "","sequence": 2,"status": 1},{"id":6, "category": 2,"title":'奥克斯转场',"url": 'http://www.baidu.com',"image": "group/M00/00/01/ADASDADA-CZXCSAasdsadada","text": "","sequence": 2,"status": 1}]
}
"""
分析首页商品广告数据结构
结论:
- 首页商品广告数据由广告分类和广告内容组成。
- 广告分类带有标识符
key
,可以利用它确定广告展示的位置。 - 确定广告展示的位置后,再查询和渲染出该位置的广告内容。
- 广告的内容还有内部的排序字段,决定了广告内容的展示顺序。
查询首页商品广告:首页广告视图文件 apps/contents/views.py
"""
首页广告视图文件 apps/contents/views.py
"""
from django.shortcuts import render
from django.views import View
from django.http import HttpResponse
from collections import OrderedDict # 有序的字典,不同于普通字典
from goods.models import GoodsChannel,GoodsCategory # 商品频道,商品类别
from .models import ContentCategory,Content # 广告内容类别,广告内容class IndexView(View):"""首页广告界面"""def get(self, request):"""提供首页界面"""# 查看并展示商品的分类categories = {}# 查询所有的商品频道# channels = GoodsChannel.objects.all()# 37个一级类别channels = GoodsChannel.objects.order_by('group_id', 'sequence') # 根据group_id排序,再根据组内顺序sequence排序# 遍历所有频道for channel in channels:group_id = channel.group_idif group_id not in categories: # category最顶级商品类别,如果当前频道不在顶级商品类别中categories[group_id] = {'channel': [], "sub_cats": []} # 创建需要传输的数据格式# 当前频道对应的一级类别cat1 = channel.category # cat1是对象,category是外键字段categories[group_id]['channel'].append({ # channel本身包含字典数据"id": cat1.id,"name": cat1.name, # category外键关联的name字段"url": channel.url})# 查询二级和三级类别信息for cat2 in GoodsCategory.objects.filter(parent__id=cat1.id).all(): # 通过频道对应的一级类别来查询cat2.sub_cats = [] # 创建是为了方便cat3进行添加数据categories[group_id]['sub_cats'].append({"id": cat2.id,"name": cat2.name, # cat2对象本身模型GoodsCategory的name字段"sub_cats": cat2.sub_cats})# 查询三级类别信息for cat3 in GoodsCategory.objects.filter(parent__id=cat2.id).all(): # 通过二级类别来查询三级cat2.sub_cats.append({ # 方便cat3进行添加数据到cat2的list中"id": cat3.id,"name": cat3.name,})# categories[group_id]['sub_cats'][].append({ # 这种方法添加数据,sub_cats数据无法添加# "id": cat3.id,# "name": cat3.name,# })# 查询所有的首页广告context_categories = ContentCategory.objects.all()contents = {}for context_categorie in context_categories:# contents是一个对象,根据category外键进行查询,status=True限制条件,order_by('sequence')按照sequence排序contents[context_categorie.key] = Content.objects.filter(category__id=context_categorie.id,status=True).order_by('sequence')context = {"categories": categories, # 商品频道整体拼接后的数据"contents": contents, # 首页广告信息拼接结果}return render(request, "index.html", context=context)
渲染首页商品广告
- 轮播图广告
首页界面:templates/index.html
{# 轮播图的渲染 #}<ul class="slide">{# apps/contents/views.py文件传输的contents对象,通过.index_lbt进行访问属性数据 #}{% for content in contents.index_lbt %}<li><a href="{{ content.url }}"><img src="{{ content.image }}" alt="{{ content.title }}"></a></li>{% endfor %}</ul>
前端界面显示效果如下:
Django项目实战——12—(Docker和FastDFS上传和下载文件、浏览器下载并渲染图片(nginx)、录入商品数据和图片数据、首页广告)相关推荐
- springboot项目打包为docker镜像并上传nexus私服
springboot项目docker打包镜像上传Nexus私服 1.springboot项目打包为docker镜像并上传nexus私服 1.0. 必要条件 1.1.开启docker远程访问 1.2.配 ...
- 前端上传预览文件以及下载,node后端存储文件以及返回前端文件流下载
上传文件<div class="inputBox" style="background-color: rgb(63, 137, 212);">上传文 ...
- Docker和FastDFS上传和下载文件
1. Docker安装运行FastDFS 1.获取FastDFS镜像 # 从仓库拉取镜像 $ sudo docker image pull delron/fastdfs 2.开启tracker容器 我 ...
- Django项目部署到Linux后,上传文件的时候,mkdirs创建目录OSError - Errno 13 Permission denied
1.今天,在Linux下安装了wkhtmltopdf,在导出pdf的时候遇到了一个问题,就是导出的时候,mkdirs的时候权限拒绝,主要抛出异常代码在下面if语句后的一行: if not os.pat ...
- docker 安装upload-lobs上传提示../upload 文件不存在解决
进入容器 docker exec -it 50ccef48fc1d /bin/bash 在/var/www/html目录下添加upload文件夹 然后赋予777权限,即可
- Ruoyi实现单文件上传和多文件打包压缩包下载
目录 单文件上传篇 1.html 2.JS 3.Controller 3.1 Global.getProfile() 3.3.1 JarBasePath.getBaseJarPathStr() 3.2 ...
- Django项目实战——用户投票系统(三)
Django项目实战--用户投票系统(三) 承接上文 官方文档链接附上: 编写你的第一个 Django 应用,第 3 部分 | Django 文档 | Django (djangoproject.co ...
- python django项目实例_最新Django项目实战-从零开发NB的任务平台python视频学习教程...
saas导学视频 .mp4 │ 模态框.zip │ ├─day01 │ │ 01 day01 sass项目介绍 .mp4 │ │ 02 day01 sass项目演示 .mp4 │ │ 04 day01 ...
- Django项目实战: Django + PyPDF2实现PDF页面提取和PDF文件输出
在日常工作中我们经常需要从一个大的PDF文档中提取我们所需要的页面,所以今天我们将教你用Django + PyPDF2开发个小Web应用: 用户上传一个PDF文档,输入需要提取的页面号码,点击确定后浏 ...
- [Docker]Docker拉取,上传镜像到Harbor仓库
需求 因为项目的需求,需要制作一个基于tomcat的镜像.那么前提就是,需要有tomcat的基础镜像. 怎么做 我的思路跑偏了,本来以为是需要将tomcat下载下来,然后通过docker命令,让它成为 ...
最新文章
- sersync进行实时同步数据
- 如何获取当前点击元素的某个子元素
- Java基础:常用IO流
- web ch6 表单基础(部分选学)
- chrome怎么隐藏浏览器_如何使用Google Chrome的隐藏阅读器模式
- [转载]Python量化交易平台开发教程系列0-引言
- 简单的oracle备份恢复批处理文件 -- 转
- html dom 知乎,知乎登录页 - 粒子运动效果
- 火狐浏览器摄像头权限怎么开启 火狐浏览器摄像头权限开启的方法
- rabbitmq消息持久化,避免异常情况下,消息会丢失
- 全志A31S(android 4.2/4.4)截屏
- fri什么意思_卡西欧fri什么意思
- 论文笔记——CPN(Corner-Proposal-Network)Det
- Debian7虚拟机安装
- 【Node.js 微信公众号实战】4.Node.js 微信消息管理
- RobotFramework set global/suite/test variable
- 企业微信三方开发:注册企业微信服务商
- 微波信号发生器典型应用——TFN TG115 微波信号发生器 100KHz-15GHz
- 新装linux系统环境配置
- 涛思数据TDengine征稿 — 保姆级教程TDengine客户端服务器安装教程
热门文章
- 【整理】显微镜下人体细胞视频合集
- android 图标的格式,Android应用图标适配
- 创建物理卷报错Can‘t open /dev/sdb5 exclusively. Mounted filesystem的问题解决过程记录
- 分享教程,制作Srt字幕最简单的方法
- 句子迷 2015_01_10
- 从程序员到项目经理(28):该死的结果导向(只看结果,不问过程到底行不行?)
- 佛罗里达州立大学计算机专业排名,佛罗里达州立大学有哪些专业_专业排名(QS世界排名)...
- 【githubshare】开源的小说下载与阅读工具:Uncle 小说。目录解析与书源结合,支持有声小说与文本小说,可下载 mobi、epub、txt 格式文本小说
- 四、回归分析之线性回归模型构建
- 我,是广工的一名电商男孩。喜欢唱跳 rap 我们终究会遇见 有缘 李伟鸿