Django models.FileField 信息上传至腾讯云 COS 存储桶
准备工作
去腾讯云上申请个存储桶, 记得权限里面打开公有读, 否则链接无法打开吗会提示访问权限被拒绝
然后准备cos 外部对接的凭证注意自己的存储桶的name 和 region 等下都要用到
代码
配置准备好这些
COS_SECRET_ID = "..." COS_SECRET_KEY = "..." REGION = "..." BUCKET = "..."
写一个存储类
import random import time from hashlib import sha1 from django.conf import settings from django.core.files.storage import Storage from django.utils.deconstruct import deconstructible from qcloud_cos import CosConfig, CosS3Client secret_id = settings.COS_SECRET_ID secret_key = settings.COS_SECRET_KEY region = settings.REGION bucket = settings.BUCKET config = CosConfig(Region=region, Secret_id=settings.COS_SECRET_ID, Secret_key=settings.COS_SECRET_KEY) client = CosS3Client(config) host = 'https://' + bucket + '.cos.' + region + '.myqcloud.com/' @deconstructible class CosStorage(Storage): def save(self, name, content, max_length=None): suffix = name.split('.')[-1] key = self.generate_key(suffix) try: client.put_object( Bucket=bucket, Body=content.read(), Key=key, EnableMD5=False ) except Exception as e: raise return host + key def generate_key(self, suffix): random_str = ''.join([str(random.randint(1, 9)) for i in range(3)]) file_name = str(int(time.time() * 10000000)) + random_str s = sha1() s.update(file_name.encode('utf-8')) file_name = str(s.hexdigest()) key = f"{file_name}.{suffix}" return key def url(self, name): return name
models.py 中的设定 storge 为自定义的 cos存储类
icon_file = models.FileField(verbose_name='头像文件', storage=CosStorage(), null=True, blank=True, max_length=256)
效果
在admin 中可以看到文件的连接, 上传保存后的文件会自动保存在 cos 对应的 存储桶中
访问链接后可以打开图片即可
其他
到此已经实现了需求, 但是仍然存在一个问题, 上传上去的图片永远无法删除
因为不论是修改还是创建都是一样的走 save 逻辑上传
期望的修改逻辑应该是将原有的文件在桶中清除
再存储类中无法实现此操作, 因此需要在序列化中重写 update 方法即可
不论是修改还是清空都可以对原有的数据进行清除
def update(self, instance, validated_data): icon_file_url = instance.icon_file.name # 如果存在更新文件, 删除老的文件 if "icon_file" in validated_data and icon_file_url: res = cos_client.delete_object( Bucket=bucket, Key=icon_file_url.split(host)[1] )return super().update(instance, validated_data)
本文来自博客园,作者:羊驼之歌,转载请注明原文链接:https://www.cnblogs.com/shijieli/p/16478153.html