静态文件迁移OSS

来源:13-6 作业:CDN OSS网站与应用加速

李嘉图principal

2020-06-02

学完老师的课程我开发了一公司内部使用的ERP系统(drf+vue)还是成就感满满的。
本来所有内容都放在ECS云服务器上,但随着使用需要,越来越发现把资源都放在一起的做法问题太多,边开发边使用(docker 镜像),海外仓库访问慢或连接不上(CDN),静态资源(主要是图片)加载慢。
现在首先想要把static中的静态资源从django项目项目拆分出来(之前包含很多产品图面整个项目有500-600M就没有使用github或者gitlab管理)
但是看了很多静态资源迁移的厂商介绍(七牛云,阿里OSS)或者网上资料也没弄明白: 基于django的orm FileField要怎么做才能既上传文件到厂商服务器,由能在model的FileField中保存文件访问路径…
目前项目中文件上传访问流程大概这样的:

model
class Import_ExportModle(models.Model):

    '''
    主要用途是来存储导入的excel路径信息
    '''

    file_id = models.IntegerField(verbose_name='file_id',primary_key=True)

    Reg_file_path_current =models.FileField(storage=OverwriteStorage(), upload_to='upload_data_file/Reg_file', verbose_name='Reg_file_path_current', null=True,
                                       blank=True)
    ......
   
view
class Import_sales0rderViewSet(viewsets.ModelViewSet):
    '''
    用Mamut script生成的salesorder更新ZWB sales order数据
    1. 上传新的salesorder到django服务器
    2. model中的路径更改
    3. 调用utils中的data restore,完成更新
    '''
    serializer_class = Import_exportSerializer
    queryset = Import_ExportModle.objects.filter(file_id=1)
url
router.register('api/Import_Export-Salesorder', Import_sales0rderViewSet, basename='import-export-salesorder')

前端

html
<td>
              <a href="javascript:" class="file-oc">Choice File
                <input type="file"  accept="application/msexcel" @change="preview_doc">
              </a>
              <el-button type="primary" size="mini" @click="submitDoC">Import Data</el-button>
              <i class="el-icon-loading" v-if="uploading===true" size="big"></i>
            </td>
api
export const import_regFile_data = (file_id, params) => {console.log(params); return axios.patch(`${host}/api/Import_Export-Regfile/${file_id}/`,params)};
vue.js
submitDoC () { //提交reg excel表

          if(this.reg_file.DoC_file){

            this.uploading=true;

            const formData = new FormData();
            //修改文件名

            formData.append('Reg_file_path_current',this.reg_file.DoC_file, `reg-file.xlsx`);
            formData.append('is_printItem',this.checked);


            import_regFile_data(1,formData).then((response)=> {
              // this.getMessage();

              this.$notify({
                title: 'Update Success',
                message: 'DoC file have been updated',
                type: 'success'
              });
              console.log(response);
              this.uploading=false;

            })
              .catch(function (error) {
              console.log(error);
              this.uploading=false;
            });

          }
        },

目前的做法实在很方便也很自然,但应该怎么讲media上传文件放到oss中,请老师指点下,非常感谢

写回答

2回答

Jack

2020-06-02

您好,你的想法是完全正确的,要实现media上传文件放到oss中,可以直接使用django_oss_storage,

先在installed_app列表加上'django_oss_storage',然后在settings中配置:

# Django AliCloud OSS Storage https://github.com/aliyun/django-oss-storage 

DEFAULT_FILE_STORAGE = 'django_oss_storage.backends.OssMediaStorage'


OSS_BUCKET_NAME = 'liaogx'

OSS_ENDPOINT = 'oss-cn-shanghai.aliyuncs.com'  # 参考 https://www.alibabacloud.com/help/zh/doc-detail/31837.htm 


OSS_ACCESS_KEY_ID = 'LTxxxxxxxxx9'

OSS_ACCESS_KEY_SECRET = 'iP5FxxxxxxxxxxO'


再把django_oss_storage/backends.py文件改下

def url(self, name):

        key = self._get_key_name(name)

        return self.bucket.sign_url('GET', key, 3600).replace('https://liaogx.oss-cn-shanghai.aliyuncs.com', 'http://img.liaogx.com').split("?")[0]

django_oss_storage其实就是调用阿里云OSS服务的接口,帮忙把前端传给后端ImageField的图片传给OSS,然后拿到图片的url,以后前端是直接访问的OSS,加上CDN访问就快了

0
4
李嘉图principal
回复
Jack
好像是覆盖原来的上传文件 from django.core.files.storage import FileSystemStorage from django.conf import settings import os class OverwriteStorage(FileSystemStorage): def get_available_name(self, name, max_length=None): if self.exists(name): os.remove(os.path.join(settings.MEDIA_ROOT, name)) return name
2020-06-03
共4条回复

Jack

2020-06-02

更改url函数是因为我使用了二级域名,开启了CDN。什么来龙去脉可以看下阿里云文档 CDN+OSS相关的配置说明

//img1.sycdn.imooc.com/szimg/5ed6179209b2098114410928.jpg

pip安装之后就是在本地,找到backends.py更改就行了。访问OSS里的文件原本url是:

http://img.liaogx.com/media%2Fmarkdownx%2Fc840a59d-59d4-4531-9b66-be4524ec5212.png?OSSAccessKeyId=LTAIPPGxfTgHMgp9&Expires=1557910467&Signature=PyveSvbVHX45N0Lpc6t%2F30PoplM%3D

split("?")[0]是为了去掉签名验证,把?OSSAccessKeyId=xxxx去掉

0
0

Django高级实战 开发企业级问答网站

融合Django高级用法/算法/设计模式/TestCase测试/云计算打造项目

900 学习 · 756 问题

查看课程