文件自动同步七牛云
起笔自
所属文集:
杂记
共计
1819
个字符
落笔于
由于服务器的带宽与存储问题,图片不得不上七牛云了。
模型
以下是一个很简单的图片模型,之前我有写过一篇Django多图片上传,所以在此不赘述如何处理图片上传部分了。
class Image(models.Model): file = models.ImageField(upload_to='upload/', verbose_name="路径") message = models.ForeignKey(Message, on_delete=models.CASCADE, verbose_name="所属消息") class Meta: verbose_name = u"图片" verbose_name_plural = u"图片"
配置七牛云
首先在项目里执行pipenv install qiniu
来安装七牛云提供的Python库。
在Django项目的settings.py
里,配置以下代码
from qiniu import Auth QINIU = Auth( access_key='YOUR ACCESS KEY', secret_key='YOUR SECRET KEY' ) BUCKET_NAME = "YOUR BUCKET NAME"
其中两个key需要自己去七牛云 - 密钥管理里看。而bucket的名字就是所需要自动同步的对象储存的储存空间名。
配置信号
import os from django.conf import settings from django.db.models.signals import pre_delete, post_save from django.dispatch import receiver from qiniu import BucketManager from qiniu import put_file, etag from .models import Image @receiver(post_save, sender=Image) def update_image(sender, instance, **kwargs): path = str(instance.file) if not path: return filepath = os.path.join(settings.MEDIA_ROOT, path) token = settings.QINIU.upload_token(settings.BUCKET_NAME, path, 3600) ret, info = put_file(token, path, filepath) assert ret['key'] == path assert ret['hash'] == etag(filepath) os.remove(filepath) # 初始化BucketManager manager = BucketManager(settings.QINIU) @receiver(pre_delete, sender=Image) def delete_image(sender, instance, **kwargs): path = str(instance.file) if not path: return ret, info = manager.delete(settings.BUCKET_NAME, path) # 无视删除错误 # assert ret == {}
利用Django的信号机制,可以在图片储存到本地之后,自动调用update_image
函数上传图片到七牛云并且删除本地的备份,如果上传失败,本地图片将不会被删除。
如果图片的模型从数据库中删除,会自动调用delete_image
函数,从七牛云的储存空间里删除对应的文件。