Logo

新人日誌

首頁關於我部落格

新人日誌

Logo

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

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

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

Django 信號處理的最佳實踐:如何選擇合適的位置

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

本文為圖片轉 WebP 功能模組化系列文,第 1 篇:

  1. 如何設計 Django 的通用工具,並選擇適合的存放位置
  2. 從零開始:如何實現圖片轉 WebP 並上傳到 S3 的功能
  3. 使用基類模型(class model)優化代碼:從零到掌握 DRY 原則
  4. Django 抽象模型:理解 class Meta: abstract = True
  5. 為什麼要分離圖片處理邏輯?Django 最佳實踐指南
  6. Django 信號處理:如何在保存前自動處理圖片
  7. Django 信號處理的最佳實踐:如何選擇合適的位置 👈 所在位置
  8. 將圖片處理移至信號:模型設計的最佳實踐
  9. 理解 Python 的方法解析順序 (MRO):Django 多重繼承的最佳實踐

建議閱讀本文前,先閱讀完 圖片轉 WebP 系列文

在 Django 中,信號(Signals)是一種強大的工具,用於在特定事件(如模型保存或刪除)發生時自動執行邏輯。

然而,當多個應用涉及信號邏輯時,信號的管理位置可能變得混亂。

本文將幫助新手理解如何選擇合適的位置存放信號邏輯,以保持代碼的結構清晰、可維護性高。


信號處理的原則

信號的處理位置應根據以下原則來確定:

  1. 信號主要針對單一應用:信號邏輯應放在該應用內的 signals.py 文件中。
  2. 信號涉及多個應用的模型:應創建一個共享的地方(如 core 或 common 應用)集中管理信號邏輯。

以下將分別介紹不同情況下的處理方式。


信號涉及多個應用的模型

當信號邏輯需要處理來自多個應用的模型時(例如,users.Profile 和 services.ServiceImage),建議將信號邏輯集中放在一個共享應用中,如 core 或 common。

步驟:創建共享應用

首先,確保項目中有一個共享應用。

如果尚未存在,可以使用以下命令創建:

python manage.py startapp core

在項目的 INSTALLED_APPS 中添加 core:

INSTALLED_APPS = [
    ...
    'core',
]

步驟:編寫信號邏輯

在 core/signals.py 文件中編寫信號邏輯。以下是一個處理用戶圖片和服務圖片的示例:

from django.db.models.signals import pre_save
from django.dispatch import receiver
from users.models import Profile
from services.models import ServiceImage

@receiver(pre_save, sender=Profile)
def process_profile_image(sender, instance, **kwargs):
    if instance.photo and not getattr(instance, '_is_photo_processed', False):
        instance._is_photo_processed = True
        instance.process_and_upload_image(instance.photo, "profile_photos/")

@receiver(pre_save, sender=ServiceImage)
def process_service_image(sender, instance, **kwargs):
    if instance.image and not getattr(instance, '_is_image_processed', False):
        instance._is_image_processed = True
        instance.process_and_upload_image(instance.image, "service_images/")

此代碼的功能:

  • process_profile_image:處理 Profile 模型中的圖片。
  • process_service_image:處理 ServiceImage 模型中的圖片。
  • 使用 _is_photo_processed 和 _is_image_processed 防止信號邏輯重複執行。

步驟:加載信號模塊

為了讓信號生效,需在共享應用的 apps.py 文件中引入 signals.py:

from django.apps import AppConfig

class CoreConfig(AppConfig):
    default_auto_field = "django.db.models.BigAutoField"
    name = "core"

    def ready(self):
        import core.signals  # 加載信號模塊

步驟:測試信號邏輯

完成上述步驟後,可以測試信號邏輯是否正確執行:

  • 創建或保存 Profile 和 ServiceImage 對象,觀察是否執行了圖片處理邏輯。
  • 確保圖片成功上傳,且避免重複處理。

信號主要針對單一應用

當信號只涉及某個應用內的模型時,可以直接將信號邏輯放置在該應用內。例如:

將信號放在 users 應用中

users/signals.py

from django.db.models.signals import pre_save
from django.dispatch import receiver
from users.models import Profile

@receiver(pre_save, sender=Profile)
def process_profile_image(sender, instance, **kwargs):
    if instance.photo and not getattr(instance, '_is_photo_processed', False):
        instance._is_photo_processed = True
        instance.process_and_upload_image(instance.photo, "profile_photos/")

users/apps.py

from django.apps import AppConfig

class UsersConfig(AppConfig):
    default_auto_field = "django.db.models.BigAutoField"
    name = "users"

    def ready(self):
        import users.signals  # 加載信號

這樣,users.Profile 的信號邏輯會直接與應用相關聯,便於管理。


如何選擇信號邏輯的位置?

以下是根據應用範圍選擇信號邏輯位置的指南:

情況處理建議
信號只涉及單個應用的模型將信號邏輯放在該應用的 signals.py 中。
信號涉及多個應用的模型將信號邏輯放在共享應用(如 core)中。
項目需要集中管理所有信號邏輯考慮創建專門的 signals 模塊,統一管理。
處理建議將信號邏輯放在該應用的 signals.py 中。
處理建議將信號邏輯放在共享應用(如 core)中。
處理建議考慮創建專門的 signals 模塊,統一管理。

總結

通過本文,你學習了如何選擇合適的位置存放 Django 的信號邏輯:

  1. 當信號邏輯針對單一應用時,將其放置在應用內。
  2. 當信號涉及多個應用時,將其集中於共享應用(如 core)。
  3. 通過正確的結構設計,提升代碼的可讀性和維護性。

遵循這些原則,你將能輕鬆管理信號邏輯,讓項目結構更清晰!

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

發表留言

留言將在審核後顯示。

Python

目錄

  • 信號處理的原則
  • 信號涉及多個應用的模型
  • 步驟:創建共享應用
  • 步驟:編寫信號邏輯
  • 步驟:加載信號模塊
  • 步驟:測試信號邏輯
  • 信號主要針對單一應用
  • 將信號放在 users 應用中
  • 如何選擇信號邏輯的位置?
  • 總結