教你如何在Django 1.6中正確使用 Signal

來源:互聯網
上載者:User
簡單回答是: 在其他方法無法使用的情況下, 才最後考慮使用signal.

因為新的django開發人員得知signal之後, 往往會很高興去使用它. 他們在能使用signal的地方就使用signal, 並且這是他們覺得自己是django專家一樣. 然而, 像這樣編碼一段時間後, django項目就會變得異常複雜, 許多內容都糾結在一起無法解開.

許多開發人員也會將django signal和非同步訊息列隊(例如celery)搞混. signal是同步處理, 因此通過signal調用大處理量的進程時並無法提高效能. 事實上, 將這些需要大處理量的進程移到signal中被視作是一種不好的習慣.

1. 何時使用signal

以下情況不要使用signal:

signal與一個model緊密相關, 並能移到該model的save()時
signal能使用model manager代替時
signal與一個view緊密相關, 並能移到該view中時
以下情況可以使用signal:

signal的receiver需要同時修改對多個model時
將多個app的相同signal引到同一receiver中處理時
在某一model儲存之後將cache清除時
無法使用其他方法, 但需要一個被調函數來處理某些問題時
2. Signal的代替方法

使用mod而來manager

以下代碼示範了當使用者建立Event model時, 需要通知管理員, 如果改寫model中的post_save(), 則需要添加額外的邏輯來區分使用者還是管理員:

# myapp/managers.py from django.db import models class EventManager(models.Manager): def create_event(self, title, start, end, creator): event = self.model(title=title, start=start, end=end, creator=creator) event.save() event.notify_admins() return event

在model中設定model manager:

# myapp/models.py from django.conf import settings from django.core.mail import mail_admins from django.db import models from model_utils.models import TimeStampedModel from .managers import EventManager class Event(TimeStampedModel): STATUS_UNREVIEWED, STATUS_REVIEWED = (0, 1) STATUS_CHOICES = ( (STATUS_UNREVIEWED, "Unreviewed"), (STATUS_REVIEWED, "Reviewed") ) title = models.CharField(max_length=100) start = models.DateTimeField() end = model.dateTimeField() status = models.IntegerField(choices=STATUS_CHOICES, default=STATUS_UNREVIEWED) creator = models.ForeignField(settings.AUTH_USER_MODEL) objects = EventManager() def notify_admins(self): subject = "{user} submitted a new event!".format(user=self.creator.get_full_name()) message = """TITLE: {title} START: {start} END: {end}""".format(title=self.title, start=self.start, end=self.end) mail_admins(subject=subject, message=message, fail_silently=False)

在view中使用create_event()代替create()時, 便會通知管理員了.

在其他代碼中驗證model

如果你使用pre_save signal來驗證某一model, 則應當嘗試自己寫一個validator取代之. 如果驗證是通過ModelForm時, 通過改寫clean()實現驗證.

使用model的save()和delete()

如果使用pre_save 或 post_save signal, 如果可以, 則將這些代碼移到model的save()方法中.

同樣如果使用pre_delete 或 post_delete signal, 如果可以, 則將這些代碼移到model的delte()方法中.

使用其他代碼代替signal

如果可能, 我們可以將signal的邏輯使用其他協助程式實現.

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.