django xadmin 结合 minio

我来为您详细介绍如何在Django中使用MinIO作为存储,并修改xadmin的文件上传部分。

1. 安装必要的依赖

bash 复制代码
pip install django-storages boto3 minio

2. 配置Django设置

settings.py中添加以下配置:

python 复制代码
# settings.py

INSTALLED_APPS = [
    # ...
    'storages',
]

# MinIO配置
MINIO_ACCESS_KEY = 'your-access-key'
MINIO_SECRET_KEY = 'your-secret-key'
MINIO_BUCKET_NAME = 'your-bucket-name'
MINIO_ENDPOINT = 'your-minio-server:9000'  # MinIO服务器地址
MINIO_USE_HTTPS = False  # 根据你的MinIO配置调整
MINIO_EXTERNAL_ENDPOINT = None  # 可选,用于生成外部URL

# Django存储后端配置
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

AWS_ACCESS_KEY_ID = MINIO_ACCESS_KEY
AWS_SECRET_ACCESS_KEY = MINIO_SECRET_KEY
AWS_STORAGE_BUCKET_NAME = MINIO_BUCKET_NAME
AWS_S3_ENDPOINT_URL = f'http://{MINIO_ENDPOINT}'  # 或 https
AWS_S3_USE_SSL = MINIO_USE_HTTPS
AWS_S3_FILE_OVERWRITE = False  # 同名文件不覆盖
AWS_DEFAULT_ACL = None  # 根据需求设置ACL
AWS_QUERYSTRING_AUTH = True  # URL是否需要认证

3. 自定义存储类(可选,用于更好的MinIO集成)

python 复制代码
# storage_backends.py
from storages.backends.s3boto3 import S3Boto3Storage
from django.conf import settings

class MinioStorage(S3Boto3Storage):
    def __init__(self, *args, **kwargs):
        kwargs['bucket_name'] = settings.MINIO_BUCKET_NAME
        kwargs['access_key'] = settings.MINIO_ACCESS_KEY
        kwargs['secret_key'] = settings.MINIO_SECRET_KEY
        kwargs['endpoint_url'] = f"http://{settings.MINIO_ENDPOINT}"
        kwargs['use_ssl'] = settings.MINIO_USE_HTTPS
        super().__init__(*args, **kwargs)

# 然后在settings.py中使用自定义存储类
# DEFAULT_FILE_STORAGE = 'your_app.storage_backends.MinioStorage'

4. 修改xadmin的文件上传

方法一:全局替换存储后端

由于xadmin使用Django的FileField,配置了DEFAULT_FILE_STORAGE后,xadmin会自动使用MinIO。

方法二:自定义xadmin的FileWidget

python 复制代码
# adminx.py
import xadmin
from xadmin.views import BaseAdminView
from django import forms
from django.db import models

class MinioFileInput(forms.ClearableFileInput):
    """自定义文件输入组件,显示MinIO文件信息"""
    
    def get_context(self, name, value, attrs):
        context = super().get_context(name, value, attrs)
        if value and hasattr(value, 'url'):
            # 显示文件的MinIO URL
            context['file_url'] = value.url
        return context

class GlobalSettings(BaseAdminView):
    # 全局设置,让xadmin使用自定义的文件widget
    global_models_icon = {
        # 你的模型图标配置
    }
    
    def get_media(self):
        media = super().get_media()
        media.add_css({'screen': [
            # 自定义CSS
        ]})
        return media

# 注册全局设置
xadmin.site.register(BaseAdminView, GlobalSettings)

方法三:为特定模型自定义表单

python 复制代码
# adminx.py
import xadmin
from django import forms
from .models import YourModel

class YourModelForm(forms.ModelForm):
    class Meta:
        model = YourModel
        fields = '__all__'
        widgets = {
            'file_field': MinioFileInput(),  # 使用自定义的文件输入组件
        }

class YourModelAdmin(object):
    form = YourModelForm
    list_display = ['name', 'file_field']
    
    # 自定义文件上传的字段显示
    def file_field_display(self, obj):
        if obj.file_field:
            return f'<a href="{obj.file_field.url}" target="_blank">下载文件</a>'
        return '无文件'
    
    file_field_display.short_description = '文件'
    file_field_display.allow_tags = True

xadmin.site.register(YourModel, YourModelAdmin)

5. 完整的配置示例

python 复制代码
# settings.py 完整配置

# MinIO配置
MINIO_ACCESS_KEY = 'minioadmin'
MINIO_SECRET_KEY = 'minioadmin'
MINIO_BUCKET_NAME = 'django-media'
MINIO_ENDPOINT = 'localhost:9000'
MINIO_USE_HTTPS = False

# AWS S3兼容配置(MinIO兼容S3 API)
AWS_ACCESS_KEY_ID = MINIO_ACCESS_KEY
AWS_SECRET_ACCESS_KEY = MINIO_SECRET_KEY
AWS_STORAGE_BUCKET_NAME = MINIO_BUCKET_NAME
AWS_S3_ENDPOINT_URL = f'http://{MINIO_ENDPOINT}'
AWS_S3_USE_SSL = MINIO_USE_HTTPS
AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = 'public-read'  # 或者 'private'
AWS_QUERYSTRING_AUTH = False  # 如果希望文件URL可以直接访问
AWS_S3_SIGNATURE_VERSION = 's3v4'

# 媒体文件配置
MEDIA_URL = f'{AWS_S3_ENDPOINT_URL}/{AWS_STORAGE_BUCKET_NAME}/'
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

6. 创建MinIO桶的初始化脚本

python 复制代码
# minio_init.py
from minio import Minio
from django.conf import settings
import logging

logger = logging.getLogger(__name__)

def create_minio_bucket():
    """创建MinIO桶(如果不存在)"""
    try:
        client = Minio(
            settings.MINIO_ENDPOINT,
            access_key=settings.MINIO_ACCESS_KEY,
            secret_key=settings.MINIO_SECRET_KEY,
            secure=settings.MINIO_USE_HTTPS
        )
        
        if not client.bucket_exists(settings.MINIO_BUCKET_NAME):
            client.make_bucket(settings.MINIO_BUCKET_NAME)
            logger.info(f"MinIO桶 {settings.MINIO_BUCKET_NAME} 创建成功")
        else:
            logger.info(f"MinIO桶 {settings.MINIO_BUCKET_NAME} 已存在")
            
    except Exception as e:
        logger.error(f"MinIO桶创建失败: {e}")

# 在Django启动时运行
# 可以在AppConfig.ready()中调用

7. 验证配置

创建一个测试视图来验证配置:

python 复制代码
# views.py
from django.http import JsonResponse
from django.core.files.storage import default_storage

def test_minio(request):
    """测试MinIO连接"""
    try:
        # 测试文件操作
        test_content = b"Hello MinIO from Django"
        file_name = "test.txt"
        
        # 保存文件
        default_storage.save(file_name, test_content)
        
        # 检查文件是否存在
        exists = default_storage.exists(file_name)
        
        # 获取文件URL
        file_url = default_storage.url(file_name)
        
        return JsonResponse({
            'status': 'success',
            'file_exists': exists,
            'file_url': file_url
        })
        
    except Exception as e:
        return JsonResponse({
            'status': 'error',
            'message': str(e)
        })

注意事项

  1. 权限配置:确保MinIO的访问策略正确设置
  2. CORS设置:如果前端需要直接上传到MinIO,需要配置CORS
  3. URL生成 :根据需求调整AWS_QUERYSTRING_AUTH设置
  4. 备份策略:制定MinIO数据的备份策略

这样配置后,xadmin的文件上传功能就会自动使用MinIO作为存储后端,所有通过FileField和ImageField上传的文件都会保存到MinIO中。

相关推荐
患得患失9497 小时前
【NestJS】NestJS三件套:校验、转换与文档生成,对比Django DRF
django·sqlite·nestjs
白云偷星子7 小时前
MySQL笔记14
数据库·笔记·mysql
绵绵细雨中的乡音8 小时前
MySQL 常用函数实操指南:从基础到实战案例
数据库·mysql
凉栀お_9 小时前
MySQL相关知识查询表中内容(第二次作业)
数据库·mysql
ss2739 小时前
手写Spring第7弹:Spring IoC容器深度解析:XML配置的完整指南
java·前端·数据库
Python私教9 小时前
DRF:Django REST Framework框架介绍
后端·python·django
PFinal社区_南丞9 小时前
PostgreSQL-10个鲜为人知的强大功能
数据库·后端
misty youth10 小时前
配置openguass 教程(自存)
数据库·ubuntu·华为·openguass
瑞士卷@11 小时前
MyBatis入门到精通(Mybatis学习笔记)
java·数据库·后端·mybatis