前文中已设计了与商品模块有关的表如下:
首页活动表用于展示一些活动图片(并附带活动链接);
首页轮播表用于展示一些轮播图片(具体轮播的效果在前端使用CSS完成);
首页展示表用于展示首页按分类排列后的一部分具体商品,展示方式意为以图片展示或以文字展示;
商品图片表用于存储商品图片,由于一种SKU商品可能有多张图片,因此将其专门提出制作一个表;
商品种类表用于存储商品的种类,即类似于水果/蔬菜/肉类此种大分类;
商品SKU与SPU表存储商品的具体信息。
注:虽然有专用于存储商品图片的商品图片表,但为了方便和减少查询次数起见还是在需要的表中添加了图片字段(用于存储一张显示于主页的图片),注意所有的图片类型其在数据库保存的都是一个图片的URL而非图片本身。
使用FastDFS保存图片
FastDFS在前文中已有过介绍,在Django中通过Nginx与FastDFS联用的方法可参考网上的方法或我的项目代码中的教程(github中),此处只描述流程。
配置FastDFS与Nginx与Django
其他部分略,在Django的配置中添加:
# 设置Django的文件存储类并指定路径,若不设置则默认为系统自带的文件存储类
DEFAULT_FILE_STORAGE = 'utils.fdfs.storage.FDFSStorage'
# 设置fdfs所需要的参数
FDFS_CLIENT_OPTION = {
'FDFS_CLIENT_CONF': './utils/fdfs/client.conf',
'BASE_URL': 'http://192.168.85.178:8888/',
'SERVER_IP': '192.168.85.178',
}
在相应的路径下即 项目主目录/utils/fdfs/storage.py 中自定义文件存储类,其需要依照Django的规范进行定义,代码如下:
from django.core.files.storage import Storage
from django.conf import settings
from fdfs_client.client import *
class FDFSStorage(Storage):
'''fdfs文件存储类'''
def __init__(self, option=None):
if not option:
self.option = settings.FDFS_CLIENT_OPTION
else:
self.option = option
def _open(self, name, mode='rb'):
'''需要返回一个文件对象,用于直接打开文件'''
pass
def _save(self, name, content):
'''保存文件时使用,name为选择上传文件的名字,content为一个包含上传文件内容的File类实例对象'''
conf = get_tracker_conf(self.option.get('FDFS_CLIENT_CONF'))
client = Fdfs_client(conf)
# 上传文件到fdfs中,根据内容上传文件
res = client.upload_by_buffer(content.read())
#res是一个字典格式的结果
if res.get('Status') != 'Upload successed.':
# 上传失败
raise Exception('上传文件失败')
filename = res.get('Remote file_id')
# 返回的内容即在数据表中保存的内容,由于返回的是bytes,将其解码
return filename.decode('utf-8')
def exists(self, name):
'''判断name在Django中是否可用,由于使用fdfs保存文件,因此直接返回False表示文件名可用'''
return False
def url(self, name):
'''返回访问文件的url路径'''
return (self.option.get('BASE_URL')+name)
配置完成后,在admin界面上传图片时就直接调用此重写的文件存储类,将数据保存于与Django关联的fdfs存储文件夹中,并返回一个拼接过的url用于访问。
浏览器访问