Skip to content

before

首先你要保证你的minio服务正常运行。

Python直接操作minio

模块下载

要求Python解释器版本3.7+。

官档:

bash
pip install minio

# 我的版本是:
pip install minio==7.2.7

快速上手

我这里只列出常用的操作,完整的操作文档参考官网:https://min.io/docs/minio/linux/developers/python/API.html

连接

python
from minio import Minio

cli = Minio(
    endpoint='127.0.0.1:9000',   # minio的服务的监听的ip和端口,我这里是本机的9000端口
    access_key='minioadmin',     # 账号
    secret_key='minioadmin',     # 密码
    secure=False
)

桶操作

python
from minio import Minio

cli = Minio(
    endpoint='127.0.0.1:9000',
    access_key='minioadmin',
    secret_key='minioadmin',
    secure=False
)

# ------------------- 桶操作 -------------------

# 检查存储桶是否存在
# cli.bucket_exists('bkt1')  # 返回布尔值 True or False

# 创建存储桶,本质上是在你的minio安装目录下创建一个文件夹
# cli.make_bucket('bkt1')  # 如果存储桶不存在则创建,桶存在则报错
# print(cli.bucket_exists('bkt1'))  # True

# 列出所有存储桶
# print(cli.list_buckets())

# 删除存储桶
# cli.remove_bucket('bkt1')
# print(cli.bucket_exists('bkt1'))

对象操作

python
from io import BytesIO
from minio import Minio

cli = Minio(endpoint='127.0.0.1:9000',access_key='minioadmin',secret_key='minioadmin',secure=False)


# 插入bytes类型的数据,必须用BytesIO转一下bytes类型
f = open(r'D:\code\dj5\media\avatars\11762339.png', 'rb')
content = f.read()
res = cli.put_object('dj5-1', 'a.png', BytesIO(content), length=len(content), content_type='image/png')
print(res)  # <minio.helpers.ObjectWriteResult object at 0x0000016C6852B200>

Django中集成minio

在Django中使用minio的话,通常有两种方式:

  1. 把之前封装的Python脚本文件,当做普通的工具类,哪里用到就导入,这种方式简单方便,所有的操作都是由我们来进行,但缺点是所有的相关逻辑都需要我们手动来完成。
  2. 使用django-minio-backend这个minio Python SDK集成到项目中, 但需要进行各种各样的配置。

使用封装的minio类

这种方式就是使用我们自己封装的关于minio的增删改查类,来结合到项目中去。

模块下载:

bash
pip install minio==7.2.7

使用django-minio-backend模块来集成minio

来学习下如何通过django-minio-backend如何集成到项目中。

参考:

bash
# --------minio服务的配置,指向9000端口给apiminio用--------
  2 server {
  3     #SSL 默认访问端口号为 443
  4     listen  443 ssl;
  5     #请填写绑定证书的域名,即apiminio.dishan.net
  6     server_name apiminio.dishan.net;
  7     #请填写证书文件的相对路径或绝对路径
  8     ssl_certificate /www/project/dishan_back/scripts/apiminio/apiminio.dishan.net.pem;
  9     #请填写私钥文件的相对路径或绝对路径
 10     ssl_certificate_key /www/project/dishan_back/scripts/apiminio/apiminio.dishan.net.key;
 11     ssl_session_timeout 5m;
 12     #请按照以下协议配置
 13     ssl_protocols TLSv1.2 TLSv1.3;
 14     #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
 15     ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
 16     ssl_prefer_server_ciphers on;
 17     gzip on;
 18     gzip_static on;
 19     gzip_min_length 1k;
 20     gzip_vary on;
 21     gzip_proxied any;
 22     gzip_comp_level 9;
 23     gzip_buffers 4 16k;
 24     gzip_http_version 1.0;
 25     # 进行压缩的文件类型
 26     gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/jpeg image/gif image/png     image/svg+xml;
 27     # 将请求转发给 MinIO 服务
 28     location / {
 29         proxy_set_header Host $host;
 30         proxy_set_header X-Real-IP $remote_addr;
 31         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 32         proxy_set_header X-Forwarded-Proto $scheme;
 33         proxy_pass http://127.0.0.1:9000;
 34         proxy_read_timeout 90;
 35     }
 36 }
 37
38 # --------guiminio服务的配置 指向9001端口给gui界面地址用--------
 39 server {
 40     #SSL 默认访问端口号为 443
 41     listen  443 ssl;
 42     #请填写绑定证书的域名,即guiminio.dishan.net
 43     server_name guiminio.dishan.net;
 44     #请填写证书文件的相对路径或绝对路径
 45     ssl_certificate /www/project/dishan_back/scripts/guiminio/guiminio.dishan.net.pem;
 46     #请填写私钥文件的相对路径或绝对路径
 47     ssl_certificate_key /www/project/dishan_back/scripts/guiminio/guiminio.dishan.net.key;
 48     ssl_session_timeout 5m;
 49     #请按照以下协议配置
 50     ssl_protocols TLSv1.2 TLSv1.3;
 51     #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
 52     ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
 53     ssl_prefer_server_ciphers on;
 54     gzip on;
 55     gzip_static on;
 56     gzip_min_length 1k;
 57     gzip_vary on;
 58     gzip_proxied any;
 59     gzip_comp_level 9;
 60     gzip_buffers 4 16k;
 61     gzip_http_version 1.0;
 62     # 进行压缩的文件类型
 63     gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/jpeg image/gif image/png     image/svg+xml;
64     location / {
 65        proxy_set_header Host $host;
 66        proxy_set_header X-Real-IP $remote_addr;
 67        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 68        proxy_set_header X-Forwarded-Proto $scheme;
 69        proxy_pass http://127.0.0.1:9001;
 70        proxy_read_timeout 90;
 71    }
bash
# --------minio服务的配置,指向9000端口给apiminio用--------

# 我理解是这样,用户只需要在前端调用apiminio.dishan.net接口就行了,在location这里直接反向代理到本机的127.0.0.1:9000
# 同理:如果从公网访问gui界面,直接用guiminio.dishan.net接口,在下面的server中反向代理到本机的127.0.0.1:9001
  2 server {
  3     #SSL 默认访问端口号为 443
  4     listen  443 ssl;
  5     #请填写绑定证书的域名,即apiminio.dishan.net
  6     server_name apiminio.dishan.net;
  7     #请填写证书文件的相对路径或绝对路径
  8     ssl_certificate /www/project/dishan_back/scripts/apiminio/apiminio.dishan.net.pem;
  9     #请填写私钥文件的相对路径或绝对路径
 10     ssl_certificate_key /www/project/dishan_back/scripts/apiminio/apiminio.dishan.net.key;
 11     ssl_session_timeout 5m;
 12     #请按照以下协议配置
 13     ssl_protocols TLSv1.2 TLSv1.3;
 14     #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
 15     ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
 16     ssl_prefer_server_ciphers on;
 17     gzip on;
 18     gzip_static on;
 19     gzip_min_length 1k;
 20     gzip_vary on;
 21     gzip_proxied any;
 22     gzip_comp_level 9;
 23     gzip_buffers 4 16k;
 24     gzip_http_version 1.0;
 25     # 进行压缩的文件类型
 26     gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/jpeg image/gif     image/png image/svg+xml;
 27     # 将请求转发给 MinIO 服务
 28     location / {
 29         proxy_set_header Host $host;
 30         proxy_set_header X-Real-IP $remote_addr;
 31         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 32         proxy_set_header X-Forwarded-Proto $scheme;
 33         proxy_pass http://127.0.0.1:9000;
 34         proxy_read_timeout 90;
 35     }
 36 }
 37
38 # --------guiminio服务的配置 指向9001端口给gui界面地址用--------
 39 server {
 40     #SSL 默认访问端口号为 443
 41     listen  443 ssl;
 42     #请填写绑定证书的域名,即guiminio.dishan.net
 43     server_name guiminio.dishan.net;
 44     #请填写证书文件的相对路径或绝对路径
 45     ssl_certificate /www/project/dishan_back/scripts/guimino/guiminio.dishan.net.pem;
 46     #请填写私钥文件的相对路径或绝对路径
 47     ssl_certificate_key /www/project/dishan_back/scripts/guimino/guiminio.dishan.net.key;
 48     ssl_session_timeout 5m;
 49     #请按照以下协议配置
 50     ssl_protocols TLSv1.2 TLSv1.3;
 51     #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
 52     ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
 53     ssl_prefer_server_ciphers on;
 54     gzip on;
 55     gzip_static on;
 56     gzip_min_length 1k;
 57     gzip_vary on;
 58     gzip_proxied any;
 59     gzip_comp_level 9;
 60     gzip_buffers 4 16k;
 61     gzip_http_version 1.0;
 62     # 进行压缩的文件类型
 63     gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/jpeg image/gif     image/png image/svg+xml;
 64     location / {
 65        proxy_set_header Host $host;
 66        proxy_set_header X-Real-IP $remote_addr;
 67        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 68        proxy_set_header X-Forwarded-Proto $scheme;
 69        proxy_pass http://127.0.0.1:9001;
 70        proxy_read_timeout 90;
 71    }
 72
 73
 74 }
 75
python
class CustomerAuthEdit(MyFirstModelViewSet):
    """
    认证页面显示的几个信息,Cuotomer_auth
    下面是上传身份证图片的
    """
    authentication_classes = [JwtAuthentication]
    filter_backends = [MineFilterBackend]
    queryset = models.CustomerInfo.objects.all()
    serializer_class = CustomerAuthEditSerializer

    @action(detail=False, methods=['post'], url_path='upload')
    def upload(self, request):
        # 获取上传的文件
        upload_object = request.FILES.get('file')
        if upload_object.size > 2 * 1024 * 1024:
            return Response({"msg": "文件太大,超过1M了,照小点,不用太清晰,不要有水印"})
        print('有文件对象1')
        bucket_name = "id-info"                                        #在桶中必须要有一个id-info的桶名
        file_name=request.user['identity_number']+upload_object.name   #保证用户身份证id和名字上传到id-info后是唯一的,每个人同名文件只能替换自己的桶占位。
        #为了方便从配置文件中拿
        minio_client = Bucket(service=settings.MINIO_BASE_URL, access_key=settings.MINIO_ADMIN,secret_key=settings.MINIO_PASSWORD,secure=settings.MINIOSECURE)
        try:
            # 如果存储桶不存在则创建
            if not minio_client.client.bucket_exists(bucket_name):
                minio_client.client.make_bucket(bucket_name)
            # 上传文件到 MinIO
            minio_client.client.put_object(bucket_name,file_name,upload_object,upload_object.size,content_type=upload_object.content_type)
            # 构建公共 URL
            file_url = f"{bucket_name}/{file_name}"
            minio_base_url = settings.MINIO_BASE_URL  # 将 MinIO 服务的基础 URL 配置在 settings 中。生产环境和开发环境不一样这是直接可以调用的地址
            #TODO:目前这里不用管,但由于这里可以直接访问到,所以要考虑以后避免直接被第三方调用的风险
            abs_file_url = f"{minio_base_url}/{file_url}"
            context = {
                "url": file_url,
                "abs_url": abs_file_url,  #这个地址
            }
            return Response(context)
        except S3Error as e:
            print("S3Error:", e)
            return Response({"msg": "文件上传失败"}, status=500)

    """day23-15参考,其它位置再补"""
    def perform_create(self, serializer):
        serializer.save(identification=2)
    def perform_update(self, serializer):
        serializer.save(identification=2)