IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Django结合七牛云实现对象云储存 -> 正文阅读

[Python知识库]Django结合七牛云实现对象云储存

目标

  1. 掌握 storage 类的导入方式
  2. 掌握 storage 类的操作模式
  3. 学会 查看七牛的文档,并为自己所用
  4. 掌握七牛的空间的创建、秘钥的获取


前言

在Django中结合第三方实现图片、文件上传的功能,现在能够实现的思路有两个,分析如下

1.1 思路一

思路:
利用七牛现有的api,单独实现一个功能模块,来完成文件对象存储。

使用方式:
在视图中,将前端传递过来的文件数据,上传七牛,然后保存七牛返回的文件地址。

优缺点:
优点:耦合性低,易修改功能代码。逻辑简单,易操作。

1.2 思路二

思路:
继承Django的 Storage 存储类,然后在自定义的存储类中,完成上传七牛,获取文件地址的逻辑,然后以及保存的逻辑。

使用方式:
学习继承 Storage 类的要点,通过自定义逻辑封装成类,在 ImageFiled 中通过 storage 参数指向自定的类

优缺点:
能够很好的利用Django的组件,完成自定逻辑。通过Django的模型类来实现图片的增删改查,例如:自带的admin管理系统,DRF的序列化操作等。

七牛官网有写好的api,大家可以参考官网api的使用完成上述逻辑。

官方网站注册地址 https://developer.qiniu.com/

官方SDK文档 https://developer.qiniu.com/kodo/sdk/1242/python


学习 Storage 类的使用

Storage类提供了用于存储文件的标准化API,以及所有其他存储系统可以根据需要继承或覆盖的一组默认行为。

如果需要提供自定义文件存储(一个常见的示例是在某个远程系统上存储文件),则可以通过定义自定义存储类来实现。

2.1 创建存储类

您的自定义存储系统必须是 django.core.files.storage.Storage 的子类:

from django.core.files.storage import Storage

class QiNiuStorage(Storage):
      pass

2.2 添加装饰器

自定义的存储类必须是 deconstructible,以便在迁移中的字段上使用它时可以序列化。 只要你的字段有自己的参数 serializable,你可以使用 django.utils.deconstruct.deconstructible 类装饰器。

from django.utils.deconstruct import deconstructible
from django.core.files.storage import Storage

@deconstructible
class QiNiuStorage(Storage):
      pass

2.3 了解Storage类

Storage模型类 作为一个基本存储类,给我们提供一些存储系统默认拥有的方法,这些方法可以被继承或重写。

Storage模型类 提供的方法中,save() 方法 和 open() 方法中使用了未定义的 _open()以及 _save()。因此在自定义模型类时,除了自定义的方法外,我们必须继承或重写 _open()以及 _save()方法。

其他的方法如果不重写,在默认情况下,会引发 NotImplementedError异常,因此在使用时,需要将其覆盖:

  • Storage.delete()
  • Storage.exists()
  • Storage.listdir()
  • Storage.size()
  • Storage.url()

注意点:

这些方法并非都是必需的,因此可以有意省略。 碰巧的是,有可能使每个方法都未实现,而仍然可以使用存储。

举例说明

  1. 如果列出某些存储后端的内容确实很昂贵,则可以决定不实现 Storage.listdir

  2. 仅处理写入文件的后端。 在这种情况下,您将不需要实现任何上述方法。

最终,由您决定采用哪种方法。 保留一些未实现的方法将导致部分(可能已损坏)接口。

通常,您还需要使用专门为自定义存储对象设计的挂钩

from django.utils.deconstruct import deconstructible
from django.core.files.storage import Storage

@deconstructible
class QiNiuStorage(Storage):
    
    def __init__(self):
      """初始化参数"""
      pass
    
    def open(self):
      """打开"""
      pass
    
    def save(self):
      """保存"""
      pass
    
    def exists(self):
      """判断文件是否存在"""
      pass
    
    def delete(self):
      """删除"""
      pass
    
    def url(self):
      """获取url地址"""
      pass

2.4 获取参数

Django必须能够在没有任何参数的情况下实例化您的存储系统。 这意味着任何设置都应来自 django.conf.settings

from django.core.files.storage import Storage
from django.conf import settings

@deconstructible
class QiNiuStorage(Storage):
    """七牛云存储"""

    def __init__(self, child_name):
        # 访问图片的根地址
        self.__base_url = settings.QINIU_BASE_URL
        # 存储图片的空间名
        self.__backet_name = settings.QINIU_BACKET_NAME
        # 七牛 access_key
        self.__access_key = settings.QINIU_ACCESS_KEY
        # 七牛 secret_key
        self.__secret_key = settings.QINIU_SECRET_KEY

2.5 完整代码

import os
import datetime
import time
from django.core.files.storage import Storage
from django.utils.deconstruct import deconstructible
from django.conf import settings
from qiniu import Auth, put_data, BucketManager


@deconstructible
class QiNiuStorage(Storage):
    """七牛云存储"""

    def __init__(self, child_name):
        # 访问图片的根地址
        self.__base_url = settings.QINIU_BASE_URL
        # 存储图片的空间名
        self.__backet_name = settings.QINIU_BACKET_NAME
        # 七牛 access_key
        self.__access_key = settings.QINIU_ACCESS_KEY
        # 七牛 secret_key
        self.__secret_key = settings.QINIU_SECRET_KEY

        # 七牛云-构建鉴权对象
        self.qiniu_server = Auth(self.__access_key, self.__secret_key)

        # 存储图片的子空间名
        self.child_name = child_name

    def _open(self, name, mode='rb'):
        """不需要打开文件,所以直接忽略"""
        pass

    def _save(self, name, content):
        """
        存储函数
        :param name: 文件名
        :param content: 文件
        :return:
        """

        # 七牛云-生成上传 Token,可以指定过期时间等
        token = self.qiniu_server.upload_token(self.__backet_name)

        # 获取文件二进制内容
        file_data = content.file

        # 利用七牛的put_data方法上传文件内容
        ret, info = put_data(
            token,
            self.__new_name(name, self.child_name),
            file_data if isinstance(file_data, bytes) else file_data.read(),
        )

        # 根据七牛的返回结果中的响应状态码,判断是否上传成功
        if info.status_code == 200:
            return ret.get("key")
        else:
            raise Exception("上传七牛失败")

    def exists(self, name):
        """
        判断文件是否存在,7牛云可以自动判断文件名是否以存在
        所以此处返回false,告诉django上传的文件都是新的
        :param name: 文件名
        :return: False
        """
        return False

    def url(self, name):
        """
        返回文件的完整URL路径
        :param name: 数据库中保存的文件名
        :return: 完整的URL
        """
        return os.path.join(self.__base_url, name)

    def delete(self, name):
        bucket = BucketManager(self.qiniu_server)
        ret, info = bucket.delete(self.__backet_name, name)
        if ret == {} and info.status_code == 200:
            return True
        else:
            raise Exception('对象存储异常!')

    @staticmethod
    def __new_name(name, child_name='article'):
        """
        将上传的文件重新命名
        :param name: 文件名
        :param child_name: 子空间域名
        :return: 新的文件名
        """
        # 获取文件后缀
        file_extension = name.split('.').pop()
        # 获取当前的时间:年_月_日,作为二级文件夹的名字
        now_time = datetime.datetime.now().strftime("%Y_%m_%d")
        # 因为业务量级不大,所以以时间戳为文件名字
        name = int(time.time())
        # 整理路径,并返回
        new_name = f"file/bigevent/{child_name}/{now_time}/{name}.{file_extension}.png"
        return new_name
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:19:14  更:2022-03-30 18:22:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 19:54:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码