見出し画像

トロが伝授!DjangoでGCPを使って画像アップロードをクラウドに任せる方法

こんにちは!お寿司界のエンタメ担当、タケトロです!今日はみなさんに、DjangoとGoogle Cloud Platform(GCP)を駆使して、画像をローカルストレージに保存せずにクラウドにアップロードする方法をお伝えしちゃいます!もちろん、トロがユーモアを交えながら解説しますから、安心してついてきてくださいね。ちょっとしたスパイスが効いていますけど、内容はしっかり実践的ですからね!

さて、Djangoでアプリケーションを作っている皆さん、画像アップロードの実装って避けて通れないですよね?でも、ちょっと待って!画像をローカルストレージに保存してしまうと、後で「あれ?この画像、どこに行ったんだっけ?」って焦ることになりますし、サーバー容量だってあっという間にいっぱいに…。お寿司でも、冷蔵庫がいっぱいだと、ネタが傷んでしまうじゃないですか?それと同じことなんです。

そこで登場するのが、Google Cloud Storage(GCS)!これを使うと、画像ファイルをローカルのストレージに保存することなく、スムーズにクラウド上にアップロードできちゃいます。しかも、GCSにアップロードされた画像は、いつでもどこでも確認できるから、まるでお寿司のようにいつでも新鮮!しかも、サーバー容量を心配する必要もありません。最高ですね!

1. GCPの設定を整えよう!

まずは、Google Cloud Platformの準備をしましょう。ここでは、GCS(Google Cloud Storage)を使用するための設定を行います。これがちゃんとできれば、画像アップロードがスムーズに進みますよ。以下の手順でセットアップを行いましょう!

  1. Google Cloud Storageのバケット作成 GCSに画像を保存するための「バケット」を作成します。これは、画像を入れるための「箱」のようなものです。Google Cloudのコンソールにログインして、バケットを作成しましょう。

  2. サービスアカウントの設定 DjangoからGCSにアクセスするために、サービスアカウントを設定します。サービスアカウントの鍵ファイル(JSON)を取得して、Djangoプロジェクト内に保存しましょう。

  3. Djangoの設定ファイルの変更 次に、Djangoの設定ファイル(settings.py)にGCSの設定を追加します。これで、DjangoがGCSと連携できるようになります。

# --- GCPの設定
DEFAULT_FILE_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage'
GS_BUCKET_NAME = os.environ['GCS_BUCKET_NAME']
GS_PROJECT_ID = os.environ['GCS_PROJECT_ID']
GOOGLE_APPLICATION_CREDENTIALS = service_account.Credentials.from_service_account_file(
    os.path.join(BASE_DIR, 'secrets', os.environ['GCS_CREDENTIALS_FILENAME'])
)

MEDIA_URL = 'https://storage.googleapis.com/{}/'.format(GS_BUCKET_NAME)
MEDIA_ROOT = 'images'  # ここはGCSのストレージで使われるパス

これで、DjangoがGCSに画像をアップロードする準備が整いました!

2. 画像アップロードの実装

次に、実際に画像をアップロードするためのコードを実装します。Djangoで画像をモデルに追加するには、ImageFieldを使います。画像がアップロードされた際に、GCSに直接保存されるように、設定を調整します。

例えば、以下のようにモデルを作成します。

from django.contrib.auth import get_user_model
from django.db import models
from google.cloud import storage
import os

def upload_image_to(instance):
    """Uploads the image file directly to Google Cloud Storage."""
    user_id = str(instance.user.id)
    destination_blob_name = f"images/{user_id}/{os.path.basename(instance.image.name)}"

    bucket_name = os.environ['GCS_BUCKET_NAME']
    client = storage.Client()
    bucket = client.bucket(bucket_name)
    blob = bucket.blob(destination_blob_name)

    # Get the file content directly from the uploaded file
    content = instance.image.read()  # Read the file content
    content_type = instance.image.file.content_type if hasattr(instance.image.file, 'content_type') else 'application/octet-stream'

    # Upload the file content to GCS
    blob.upload_from_string(content, content_type=content_type)

    # Make the file publicly accessible
    blob.make_public()

    # Return the GCS public URL
    return blob.public_url

class Profile(models.Model):
    user = models.OneToOneField(get_user_model(), unique=True, on_delete=models.CASCADE, primary_key=True)
    image = models.ImageField(upload_to=upload_image_to, blank=True, null=True)
    
    def save(self, *args, **kwargs):
        """Override the save method to handle direct GCS upload."""
        super().save(*args, **kwargs)


このコードでは、画像がアップロードされると、GCSに自動的に保存され、公開URLが返されます。

3. 画像表示の設定

画像が無事にGCSにアップロードされたら、最後にその画像をページ上に表示する準備をしましょう。

以下のように、テンプレート内で画像を表示できます:

<img class="border rounded-circle" id="image_preview"
     src="{{ user.profile.image.url }}" 
     style="width:150px; height:150px; object-fit: cover;">

4. トラブルシューティング:よくある問題と対策

もちろん、道中にはいくつかの問題が出てくるかもしれませんが、心配しないでください!トロがしっかりフォローします。

  • 画像が表示されない: まず、GCSのバケットのアクセス権限を確認してみてください。画像を公開設定にしていない場合、アクセスできません。

  • エラーメッセージ: エラーメッセージが出たら、DjangoのログやGCPのコンソールでエラーの詳細を確認しましょう。エラーの原因を突き止めて修正します。

まとめ

これで、Djangoを使ったGCPでの画像アップロード設定が完了しました!GCSを使うことで、ローカルストレージに画像を保存する手間から解放され、スムーズに画像をクラウドに保存できます。サーバーの容量も気にせず、いつでも新鮮な画像を表示できるようになりますよ!

さあ、トロと一緒にGCPの力を使って、素晴らしいアプリケーションを作り上げましょう!さあ、次のお寿司、いや、次のプロジェクトに向けて、頑張りましょうね!

いいなと思ったら応援しよう!