概要
- djangoを使って、ファイルアップロードエンドポイントを作った際に、取得したファイルオブジェクトをそのままMinIO(https://min.io/)に投入する手順
- 備忘録
前提
- 環境
- python: v.3.7.7
- django: v.2.0.3
- minio: 5.0.13
Template
- 簡単なアップロード用のtemplateを用意する
{% extends 'base.html' %} // 必要であればベースを読み込んでおく
{% block content %}
// ファイルアップロードのためには、enctypeの記述が必要
<form method="POST" action="{% url 'upload_to_minio' %}" enctype="multipart/form-data">
{% csrf_token %}
// ファイルアップロード用 input
<p>
<label for="myfile">File:</label>
<input type="file" name="myfile" required id="myfile">
</p>
// アップロードボタン
<button type=“submit”>アップロード</button>
</form>
{% endblock %}
urs.py
- uploadのエンドポイント用URLを設定する
urlpatterns = [
path("umc/upload_to_minio/", views.UploadToMinio.as_view(), name="upload_to_minio"
]
views.py
- アップロードされたファイル情報を取得し、MinIOに格納するロジックを記載する
class UploadToMinio(generic.View, LoginRequiredMixin):
def post(self, request, *args, **kwargs):
try:
# アップロードされたファイルは、request.FILESに格納されている
myfile = self.request.FILES['myfile']
# ファイルのバイナリデータをメモリ上に読み込む
# 巨大ファイルを取り扱う場合は注意
file_obj = myfile.read()
# ファイルサイズを取得
file_size = myfile.size
# 格納先のbucket名
bucket_name = 'hoge'
# 格納先のobject名
object_name = 'fuga'
# minio client
minioClient = Minio(
'host:port', # MinIOのアクセス先
access_key='access_key', # 各環境のaccess_key
secret_key='secret_key', # 各環境のsecret_key
secure=True) # https通信の場合はTrue
# bucketが存在しなければ作成する
if not minioClient.bucket_exists(project_id):
minioClient.make_bucket(bucket_name=bucket_name)
# objectの作成
minioClient.put_object(
bucket_name=project_id,
object_name=uuid,
data=io.BytesIO(file_obj),
length=file_size
)
-
put_object
のdata
はio.RawIOBase
を継承したオブジェクトしか受け付けない。そのため、 メモリ上のオブジェクトに対してio.BytesIO()
でバイナリストリーム化してあげる。
これで動くはず