Logo

新人日誌

首頁關於我部落格

新人日誌

Logo

網站會不定期發佈技術筆記、職場心得相關的內容,歡迎關注本站!

網站
首頁關於我部落格
部落格
分類系列文

© 新人日誌. All rights reserved. 2020-present.

如何在 Django 中處理用戶圖片並自動轉換為 WebP 格式

最後更新:2024年12月21日Python

本文為 Django 圖片轉 webp 系列教學,第 3 篇:

  1. 圖片轉換為 WebP 格式並存儲到 AWS S3 的完整指南
  2. 如何決定儲存 WebP 圖片的方式:覆蓋與直接存儲解析
  3. 如何在 Django 中處理用戶圖片並自動轉換為 WebP 格式 👈 所在位置
  4. 使用 Django 和 AWS S3 實現圖片存儲:基礎指南
  5. 如何在 Django 中使用 Pillow 處理圖片並轉換為 WebP 格式
  6. 如何使用 UUID 為圖片生成唯一文件名:Django 文件處理實例
  7. 使用 Boto3 將 WebP 圖片上傳到 AWS S3:完整指南
  8. 解決 AWS S3 HeadObject 錯誤 (403 Forbidden):詳細指南
  9. 解決圖片重複上傳到 AWS S3 的問題:給新手的指南
  10. 如何避免重複存儲不同格式圖片在 AWS S3:新手指南
  11. 理解 Django 文件字段的行為:新手指南

建議閱讀本文前,先閱讀完 圖片上傳 AWS 功能 系列文

在現代的 web 開發中,圖片的高效處理對於提升網站性能至關重要。

WebP 格式因其優異的壓縮能力,已成為優化圖片加載速度的最佳選擇之一。

本篇文章將教您如何在 Django 中實現用戶圖片的上傳與管理,並通過自動轉換為 WebP 格式,將優化後的圖片存儲到 AWS S3。


目標功能

本文的代碼將實現以下功能:

  1. 用戶可以上傳個人圖片。
  2. 系統將圖片自動轉換為 WebP 格式。
  3. 處理後的圖片自動上傳到 AWS S3。
  4. 模型中的圖片字段自動更新為存儲在 S3 上的 WebP 圖片的 URL。

完整代碼

以下是完整的 Profile 模型代碼,實現上述功能:

from django.db import models
from django.contrib.auth.models import User
from PIL import Image
from io import BytesIO
import boto3
import uuid
from django.conf import settings


class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
    photo = models.ImageField(upload_to="profile_photos/", blank=True, null=True)
    bio = models.TextField(max_length=200, null=True)
    location = models.CharField(max_length=50, null=True)
    is_client = models.BooleanField(default=True, null=True)
    is_freelancer = models.BooleanField(default=False, null=True)
    freelancer_verified = models.BooleanField(default=False, null=True)

    def save(self, *args, **kwargs):
        """
        保存模型時,自動將上傳的圖片轉換為 WebP 格式並上傳到 AWS S3,
        同時將 photo 字段更新為 WebP 圖片的 S3 URL。
        """
        # 保存原始圖片,確保能獲取文件對象
        super().save(*args, **kwargs)

        if self.photo:  # 確保 photo 字段存在
            try:
                # 打開圖片並轉換為 WebP 格式
                image = Image.open(self.photo)
                webp_image_io = BytesIO()
                image.save(webp_image_io, format="WEBP", quality=85)
                webp_image_io.seek(0)

                # 生成唯一文件名
                unique_filename = f"profile_photos/{uuid.uuid4()}.webp"

                # 上傳到 S3
                s3 = boto3.client('s3', region_name=settings.AWS_S3_REGION_NAME)
                s3.upload_fileobj(
                    webp_image_io,
                    settings.AWS_STORAGE_BUCKET_NAME,
                    unique_filename,
                    ExtraArgs={"ContentType": "image/webp"}
                )

                # 覆蓋 photo 字段為 WebP 文件的 S3 URL
                self.photo.name = unique_filename

                # 再次保存模型,更新 photo 字段
                super().save(*args, **kwargs)
            except Exception as e:
                print(f"圖片處理或上傳失敗:{e}")

    def __str__(self):
        """
        返回用戶名及其 Profile 的表示。
        """
        return f"{self.user.username}'s Profile"

功能解析

模型字段介紹

  • user 字段
    定義 Profile 與內建 User 模型的一對一關係,讓每個用戶對應一個 Profile。
  • photo 字段
    儲存上傳的用戶圖片。圖片將存放於 profile_photos/ 文件夾下,並支持空值。
  • 其他字段
    • bio 和 location:分別用於儲存用戶簡介和地理位置。
    • is_client 和 is_freelancer:標識用戶的角色類型。
    • freelancer_verified:標記自由職業者的驗證狀態。

自定義 save() 方法

圖片處理與存儲的完整流程:

  1. 保存原始圖片
    調用父類的 save() 方法,先保存用戶上傳的原始圖片。
  2. 轉換為 WebP 格式
    使用 Pillow 庫將圖片轉換為 WebP 格式,並將處理後的圖片保存在內存中。
  3. 生成唯一文件名
    為每張圖片生成唯一的文件名,避免因重名導致的衝突。
  4. 上傳到 AWS S3
    使用 boto3 將圖片文件流上傳到指定的 AWS S3 存儲桶,並設置 MIME 類型為 image/webp。
  5. 更新模型字段
    將 photo 字段的值更新為存儲在 S3 上的 WebP 圖片 URL,並再次保存模型。

AWS S3 的設置依賴

在使用該代碼之前,請確保已經在 settings.py 文件中正確配置了 AWS S3 的相關參數:

AWS_S3_REGION_NAME = "your-region"  # 例如 "us-east-1"
AWS_STORAGE_BUCKET_NAME = "your-bucket-name"
AWS_ACCESS_KEY_ID = "your-access-key"
AWS_SECRET_ACCESS_KEY = "your-secret-key"

優化建議

  1. 增加異常處理
    如果圖片處理或上傳過程中出現問題(例如網絡錯誤),可以記錄日誌或返回友好的錯誤信息。
  2. 性能優化
    • 減少圖片處理過程中的 I/O 操作。
    • 在高並發環境中,可以使用任務隊列(如 Celery)將圖片處理與上傳操作異步化。
  3. 圖片大小限制
    可以在上傳時驗證圖片大小,避免過大的文件影響系統性能。

結論

通過本文的實現,您可以輕鬆完成用戶圖片的上傳、轉換和存儲,並充分利用 WebP 格式的優勢提升應用性能。

同時,整合 AWS S3 讓圖片管理更加方便高效。希望這篇文章能為您提供有價值的參考,助力構建更優化的圖片處理功能!

目前還沒有留言,成為第一個留言的人吧!

發表留言

留言將在審核後顯示。

Python

目錄

  • 目標功能
  • 完整代碼
  • 功能解析
  • 模型字段介紹
  • 自定義 save() 方法
  • AWS S3 的設置依賴
  • 優化建議
  • 結論