教你如何在Django 1.6中正確使用 Signal
簡(jiǎn)單回答是: 在其他方法無(wú)法使用的情況下, 才最后考慮使用signal.
因?yàn)樾碌膁jango開(kāi)發(fā)人員得知signal之后, 往往會(huì)很高興去使用它. 他們?cè)谀苁褂胹ignal的地方就使用signal, 并且這是他們覺(jué)得自己是django專家一樣. 然而, 像這樣編碼一段時(shí)間后, django項(xiàng)目就會(huì)變得異常復(fù)雜, 許多內(nèi)容都糾結(jié)在一起無(wú)法解開(kāi).
許多開(kāi)發(fā)者也會(huì)將django signal和異步消息列隊(duì)(例如celery)搞混. signal是同步處理, 因此通過(guò)signal調(diào)用大處理量的進(jìn)程時(shí)并無(wú)法提高性能. 事實(shí)上, 將這些需要大處理量的進(jìn)程移到signal中被視作是一種不好的習(xí)慣.
1. 何時(shí)使用signal
以下情況不要使用signal:
signal與一個(gè)model緊密相關(guān), 并能移到該model的save()時(shí)
signal能使用model manager代替時(shí)
signal與一個(gè)view緊密相關(guān), 并能移到該view中時(shí)
以下情況可以使用signal:
signal的receiver需要同時(shí)修改對(duì)多個(gè)model時(shí)
將多個(gè)app的相同signal引到同一receiver中處理時(shí)
在某一model保存之后將cache清除時(shí)
無(wú)法使用其他方法, 但需要一個(gè)被調(diào)函數(shù)來(lái)處理某些問(wèn)題時(shí)
2. Signal的代替方法
使用mod而來(lái)manager
以下代碼演示了當(dāng)用戶創(chuàng)建Event model時(shí), 需要通知管理員, 如果改寫(xiě)model中的post_save(), 則需要添加額外的邏輯來(lái)區(qū)分用戶還是管理員:
# 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中設(shè)置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()時(shí), 便會(huì)通知管理員了.
在其他代碼中驗(yàn)證model
如果你使用pre_save signal來(lái)驗(yàn)證某一model, 則應(yīng)當(dāng)嘗試自己寫(xiě)一個(gè)validator取代之. 如果驗(yàn)證是通過(guò)ModelForm時(shí), 通過(guò)改寫(xiě)clean()實(shí)現(xiàn)驗(yàn)證.
使用model的save()和delete()
如果使用pre_save 或 post_save signal, 如果可以, 則將這些代碼移到model的save()方法中.
同樣如果使用pre_delete 或 post_delete signal, 如果可以, 則將這些代碼移到model的delte()方法中.
使用其他代碼代替signal
如果可能, 我們可以將signal的邏輯使用其他幫助程序?qū)崿F(xiàn).
相關(guān)文章
Python中字符串列表的相互轉(zhuǎn)換實(shí)際應(yīng)用場(chǎng)景
在Python編程中,經(jīng)常會(huì)遇到需要將字符串列表相互轉(zhuǎn)換的情況,這涉及到將逗號(hào)分隔的字符串轉(zhuǎn)換為列表,或者將列表中的元素連接成一個(gè)字符串,本文將深入討論這些情景,并提供豐富的示例代碼,幫助讀者更全面地理解字符串列表的轉(zhuǎn)換操作2023-12-12python3.7實(shí)現(xiàn)云之訊、聚合短信平臺(tái)的短信發(fā)送功能
這篇文章主要介紹了python3.7實(shí)現(xiàn)云之訊、聚合短信平臺(tái)的短信發(fā)送功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-09-09python基于機(jī)器學(xué)習(xí)預(yù)測(cè)股票交易信號(hào)
近年來(lái),隨著技術(shù)的發(fā)展,機(jī)器學(xué)習(xí)和深度學(xué)習(xí)在金融資產(chǎn)量化研究上的應(yīng)用越來(lái)越廣泛和深入。目前,大量數(shù)據(jù)科學(xué)家在Kaggle網(wǎng)站上發(fā)布了使用機(jī)器學(xué)習(xí)/深度學(xué)習(xí)模型對(duì)股票、期貨、比特幣等金融資產(chǎn)做預(yù)測(cè)和分析的文章。本文就來(lái)看看如何用python預(yù)測(cè)股票交易信號(hào)2021-05-05python利用Tesseract識(shí)別驗(yàn)證碼的方法示例
無(wú)論是是自動(dòng)化登錄還是爬蟲(chóng),總繞不開(kāi)驗(yàn)證碼,這次就來(lái)談?wù)刾ython中光學(xué)識(shí)別驗(yàn)證碼模塊Tesseract,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01GitHub上值得推薦的8個(gè)python 項(xiàng)目
GitHub 無(wú)疑是代碼托管領(lǐng)域的先行者,Python 作為一種通用編程語(yǔ)言,已經(jīng)被千千萬(wàn)萬(wàn)的開(kāi)發(fā)人員用來(lái)構(gòu)建各種有意思或有用的項(xiàng)目。以下我們會(huì)介紹一些使用 Python 構(gòu)建的GitHub上優(yōu)秀的項(xiàng)目。2020-10-10python tkinter控件布局項(xiàng)目實(shí)例
這篇文章主要介紹了python tkinter控件布局項(xiàng)目實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11關(guān)于Python列表元素排序操作sort()、min()、max()函數(shù)用法
這篇文章主要介紹了關(guān)于Python列表元素排序操作sort()、min()、max()函數(shù)用法,python中提供了列表元素的操作函數(shù),那么這些函數(shù)該怎么使用呢,感興趣的朋友一起來(lái)看看吧2023-04-04