亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術(shù)文章
文章詳情頁

正確的理解和使用Django信號(Signals)

瀏覽:29日期:2024-09-10 16:18:34

Django 提供一個了“信號分發(fā)器”機(jī)制,允許解耦的應(yīng)用在框架的其它地方發(fā)生操作時會被通知到。 通俗而講Django信號的工作原理就是當(dāng)某個事件發(fā)生的時候會發(fā)出一個信號(signals), 而監(jiān)聽這個信號的函數(shù)(receivers)就會立即執(zhí)行。Django信號的應(yīng)用場景很多,尤其是用于不同模型或程序間的聯(lián)動。常見例子包括創(chuàng)建User對象實例時創(chuàng)建一對一關(guān)系的UserProfile對象實例,或者每當(dāng)用戶下訂單時觸發(fā)給管理員發(fā)郵件的動作。今天小編我就分享下如何正確使用Django的信號(signals)。

Django信號的一個簡單例子

假設(shè)我們有一個如下User模型,我們希望每次有User對象新創(chuàng)建時都打印出有新用戶注冊的提示信息,我們可以使用Django信號(signals)輕松實現(xiàn)。我們的信號發(fā)送者sender是User模型,每當(dāng)User模型執(zhí)行post_save動作時就會發(fā)出信號。此時我們自定義的create_user函數(shù)一旦監(jiān)聽到User發(fā)出的post_save信號就會執(zhí)行,先通過if created判斷對象是新創(chuàng)建的還是被更新的;如果對象是新創(chuàng)建的,就會打印出提示信息。

# models.py

from django.db import modelsfrom django.db.models import signalsfrom django.dispatch import receiverclass User(models.Model): name = models.CharField(max_length=16) gender = models.CharField(max_length=32, blank=True)def create_user(sender, instance, created, **kwargs): if created:print('New user created!')post_save.connect(create_user, sender=User)

在上例中我們使用了信號(post_save)自帶的connect的方法將自定義的函數(shù)與信號發(fā)出者(sender)User模型進(jìn)行了連接。在實際應(yīng)用中一個更常用的方式是使用@receiver裝飾器實現(xiàn)發(fā)送者與監(jiān)聽函數(shù)的連接,如下所示。@receiver(post_save, sender=User)讀起來的意思就是監(jiān)聽User模型發(fā)出的post_save信號。

from django.db import modelsfrom django.db.models.signals import post_savefrom django.dispatch import receiverclass User(models.Model): name = models.CharField(max_length=16) gender = models.CharField(max_length=32, blank=True)@receiver(post_save, sender=User)def create_user(sender, instance, created, **kwargs): if created:print('New user created!')利用Django信號實現(xiàn)不同模型的聯(lián)動更新

我們再來看一個復(fù)雜一點的例子。我們有一個Profile模型,與User模型是一對一的關(guān)系。我們希望創(chuàng)建User對象實例時也創(chuàng)建Profile對象實例,而使用post_save更新User對象時不創(chuàng)建新的Profile對象。這時我們就可以自定義create_user_profile和save_user_profile兩個監(jiān)聽函數(shù),同時監(jiān)聽sender(User模型)發(fā)出的post_save信號。由于post_save可同時用于模型的創(chuàng)建和更新,我們用if created這個判斷來加以區(qū)別。

from django.db import modelsfrom django.db.models.signals import post_savefrom django.dispatch import receiverclass Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) birth_date = models.DateField(null=True, blank=True)@receiver(post_save, sender=User)def create_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance)@receiver(post_save, sender=User)def save_user_profile(sender, instance, **kwargs): instance.profile.save()Django常用內(nèi)置信號

之前的例子中我們使用的都是post_save信號,即在模型調(diào)用save()方法后才發(fā)送信號。Django其它常用內(nèi)置信號還包括:

django.db.models.signals.pre_save & post_save在模型調(diào)用 save()方法之前或之后發(fā)送。 django.db.models.signals.pre_init& post_init在模型調(diào)用_init_方法之前或之后發(fā)送。 django.db.models.signals.pre_delete & post_delete在模型調(diào)用delete()方法或查詢集調(diào)用delete() 方法之前或之后發(fā)送。 django.db.models.signals.m2m_changed在模型多對多關(guān)系改變后發(fā)送。 django.core.signals.request_started & request_finished Django建立或關(guān)閉HTTP 請求時發(fā)送。如何正確放置Django信號的監(jiān)聽函數(shù)代碼

在之前案例中,我們將Django信號的監(jiān)聽函數(shù)寫在了models.py文件里。當(dāng)一個app的與信號相關(guān)的自定義監(jiān)聽函數(shù)很多時,此時models.py代碼將變得非常臃腫。一個更好的方式把所以自定義的信號監(jiān)聽函數(shù)集中放在app對應(yīng)文件夾下的signals.py文件里,便于后期集中維護(hù)。

假如我們有個account的app,包含了User和Pofile模型,我們不僅需要在account文件夾下新建signals.py,還需要修改account文件下apps.py和__init__.py,以導(dǎo)入創(chuàng)建的信號監(jiān)聽函數(shù)。

# account/signals.py

from django.db.models.signals import post_savefrom django.dispatch import receiverfrom .models import User, Profile@receiver(post_save, sender=User)def create_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance)@receiver(post_save, sender=User)def save_user_profile(sender, instance, **kwargs): instance.profile.save()

# account/apps.py

from django.apps import AppConfigclass AccountConfig(AppConfig): name = ’account’ def ready(self):import account.signals

# account/__init__.py

default_app_config = ’account.apps.AccountConfig’小結(jié)

在本文里我們總結(jié)了Django信號(signals)的工作原理,介紹了如何使用Django信號實現(xiàn)模型或程序的聯(lián)動。最后我們還總結(jié)了Django常用內(nèi)置信號以及如何正確放置自定義的信號監(jiān)聽函數(shù)。歡迎關(guān)注我們更多Python Web開發(fā)和Django原創(chuàng)文章。

以上就是正確的理解和使用Django信號(Signals)的詳細(xì)內(nèi)容,更多關(guān)于Django信號(Signals)的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Django
相關(guān)文章:
主站蜘蛛池模板: 91精品国产综合久久精品 | 久久性生活片 | 午夜剧场福利 | 欧美在线成人免费国产 | 极品美女一级毛片免费 | 久久最新网址 | 男女又黄又刺激黄a大片桃色 | 国产性大片黄在线观看在线放 | 亚洲精品一区国产二区 | 国产精品免费久久久免费 | 好吊色综合网天天高清 | 成人男女网18免费看 | 国内精自品线一区91 | 永久免费的网站 | 国产欧美一区二区三区视频在线观看 | 精品一区精品二区 | 婷婷在线播放 | 一级黄色在线播放 | 国产欧美亚洲精品第一页青草 | 黄色在线资源 | 婷婷综合久久狠狠色99h | 久久精品视频在线观看 | 免费看香港一级毛片 | 国产中出视频 | 九色国产在视频线精品视频 | 亚洲精品日韩一区二区 | 国产色司机在线视频免费观看 | 国产免费观看网站黄页 | 91免费国产 | 亚洲国产精品一区 | 一级白嫩美女毛片免费 | 亚洲国产成人久久99精品 | 成人免费毛片一区二区三区 | 久久青青热| 欧美日本三级 | 蕾丝视频在线观看www | 欧美特黄高清免费观看的 | 国产精品成人免费福利 | 久久精品国产91久久综合麻豆自制 | 日产免费线路一页二页 | 久久国产精品久久久久久久久久 |