LoginSignup
2
2

More than 3 years have passed since last update.

django-storage で Google Cloud Storages へのファイル upload と delete

Last updated at Posted at 2020-01-22

背景

Djangoのライブラリであるdjango-storagesを使ったGoogle Cloud Stoargeファイルのdelete方法を試行錯誤で解決したので、upload方法もふくめてそのメモをまとめておきます。

方法

django-storagesのページに基本的な設定方法が書かれています。

settings.py
DEFAULT_FILE_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage'
GS_BUCKET_NAME = 'YOUR_BUCKET_NAME_GOES_HERE'

と、

settings.py
from google.oauth2 import service_account

GS_CREDENTIALS = service_account.Credentials.from_service_account_file(
    "path/to/credentials.json"
)

の2点を記述して通常通りモデルを定義しておけばuploadまでは動作します。
以下は画像ファイルのモデル例です。

models.py
class Image(models.Model):
    image = models.ImageField(upload_to='image/')

    def __str__(self):
        return self.image.name

ただ、ここまでだと、レコードを削除してもGoogle Cloud Storageのファイルは消してくれません。これは(二次情報を読んだだけですが)Django自体の設計思想として、Google Cloud Storageを使う場合に限らず、ファイル削除は自分で実装することとしているようです。

その実装にはレコード削除時に呼ばれる関数をデコレータを使って定義する必要があります。
Google cloud consoleでファイル削除すると(本処理時にGoogle Cloud Storage側にファイルが無い場合)エラーが発生するので例外処理を入れています。

models.py
from django.dispatch import receiver
from google.cloud import exceptions

@receiver(models.signals.post_delete, sender=Image)
def auto_delete_image(sender, instance, **kargs):
    file = instance.image
    try:
        file.storage.delete(name=file.name)
    except exceptions.NotFound as e:
        print(e)

環境変数GOOGLE_APPLICATION_CREDENTIALSを設定していればgoogle.cloudのモジュールで以下のようにも実装できます。
ただ、この場合google cloudの権限として、storage.buckets.getを割り当てておかないとエラーになりました。

model.py
from google.cloud import storage
from django.conf import settings

@receiver(models.signals.post_delete, sender=Image)
def auto_delete_image(sender, instance, **kargs):
    storage_client = storage.Client()
    bucket = storage_client.get_bucket(settings.GS_BUCKET_NAME)
    blob = bucket.blob(instance.image.name)
    try:
        blob.delete()
    except exceptions.NotFound as e:
        print(e)

補足

Google Cloud Storage側の設定を補足しておきます。しっかり検証していないのですべては不要かもしれませんが私の環境では以下の権限を割り当てたサービスアカウントを発行してます。

  • storage.objects.create
  • storage.objects.delete
  • storage.objects.get
  • storage.objects.list
  • storage.objects.update

実際の設定方法は公式のリンクを載せておきます。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2