目录
一、配置admin上传图片到阿里云oss
二、配置admin后台上传到阿里云oss的图片为自定义名
问题描述:在开发自己的应用/网页前后台时可以调用阿里云oss的接口将图片上传至oss保存和读取,非常方便。但在django自带的admin后台中如何配置添加的图片也上传到阿里云oss中保存呢?
一、配置admin上传图片到阿里云oss
1,models模型
class Product(models.Model):
"""常规商品"""
name = models.CharField(verbose_name="商品名称", max_length=50)
desc = models.TextField(verbose_name="描述")
show_img = models.ImageField(verbose_name="展示图", upload_to='images/')
detail_img = models.ImageField(verbose_name="详情图", upload_to='images/')
is_sale = models.BooleanField(verbose_name="是否上架", default=False) # 为False时是下架
is_show = models.BooleanField(verbose_name="是否展示在首页", default=True) # 为True时是展示在首页
create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
update_time = models.DateTimeField(auto_now=True, verbose_name="最后一次修改时间")
def __str__(self):
return self.name
class Meta:
verbose_name = "常规商品"
verbose_name_plural = verbose_name
2,配置media,支持图片上传
settings.py
# settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
项目根urls.py
# urls.py 添加media配置
from django.views.static import serve
from django.urls import path, include, re_path
urlpatterns = [
path('admin/', admin.site.urls),
path('users/', include('users.urls')),
path('goods/', include('goods.urls')),
# 新增media配置
re_path(r'^media/(?P<path>.*)$', serve, {"document_root": settings.MEDIA_ROOT}),
]
3,安装所需的模块
安装django-aliyun-oss2-storage,参考github上的 配置安装django-aliyun-oss2-storage
pip install -i https://pypi.douban.com/simple django-aliyun-oss2-storage
如果pip安装不成功,可以到github中下载下来源码,解压后进入到setup.py所在的目录使用python setup.py install命令安装(过程中可能会报错,根据报错提示修改一下源码即可成功安装)
4,settings.py中的相关配置
# admin后台上传图片到oss
DEFAULT_FILE_STORAGE = 'aliyun_oss2_storage.backends.AliyunMediaStorage' # 默认admin 上传oss配置
ACCESS_KEY_ID = "40ZhE1HyuWdllpMh"
ACCESS_KEY_SECRET = "KbxtlKSvKyuyuymTiQvrxhsYFMguXy"
END_POINT = "oss-us-west-1.aliyuncs.com"
BUCKET_NAME = "XXXX"
ALIYUN_OSS_CNAME = "" # 自定义域名,如果不需要可以不填写
BUCKET_ACL_TYPE = "private" # private, public-read, public-read-write
# private:仅创建者可以访问对象,默认值。
# public-read:所有人都可以读取对象,但只有创建者可以写入。
# public-read-write:所有人都可以读取和写入对象,不推荐使用。
# authenticated-read:所有 AWS 用户都可以读取对象,但只有创建者可以写入。
# aws-exec-read:Amazon EC2 实例可以读取对象,但只有创建者可以写入。
# bucket-owner-read:存储桶所有者可以读取对象,但其他人不行。
# bucket-owner-full-control:存储桶所有者可以读取和写入对象,其他人不行。
至此,再次在admin后台中添加图片保存时就可以自动上传到阿里云oss中了
二、配置admin后台上传到阿里云oss的图片为自定义名
问题:admin后台在上传图片保存到oss时,会直接使用上传时的图片名称,这样会导致当存在同名文件上传时会替换掉之前上传的同名文件,这并不是我们想要的结果,所以对上传的图片进行自动生成不重复的名称就显得尤为重要!
1,重写默认方法
import os
from aliyun_oss2_storage.backends import AliyunMediaStorage
class AdminMediaStorage(AliyunMediaStorage):
"""重写AliyunMediaStorage自定义admin后台上传到阿里云oss的图片名称"""
def get_available_name(self, name, max_length=None):
# 生成admin后台自定义的图片名称
ext = name.split('.')[-1]
filename = '{}.{}'.format(uuid.uuid4().hex, ext)
return super().get_available_name(filename, max_length), name
def _save(self, name, content):
# 获取存储路径并保存到阿里云OSS
path = os.path.split(name[1])
if getattr(content, 'content_type', None) is None:
content_type = mimetypes.guess_type(name)[0]
content.content_type = content_type
return super()._save(path[0] + '/' + name[0], content)
注:我这里重写的_save方法最后调用的了超类的_save方法的第一个参数是拼接了阿里云oss里保存文件的路径,如user/image/head_img.png
2,修改settings.py中原有的配置
原配置
DEFAULT_FILE_STORAGE = 'aliyun_oss2_storage.backends.AliyunMediaStorage'
替换为
DEFAULT_FILE_STORAGE = 'goods.admin.AdminMediaStorage' # 自定义admin 上传oss配置