欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Django signals 信號(hào)作用及用法詳解

 更新時(shí)間:2020年03月28日 11:46:40   作者:陌上花開緩緩歸!  
這篇文章主要介紹了基于Django signals 信號(hào)作用及用法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧

1、Model signals

django.db.models.signales 作用于django的model操作上的一系列信號(hào)

1)pre_init()

django.db.models.signals.pre_init

當(dāng)模型實(shí)例化時(shí)調(diào)用,在__init__()之前執(zhí)行

三個(gè)參數(shù):

pre_init(sender, args, kwargs):

sender:創(chuàng)建實(shí)例的模型類

args:參數(shù)列表

kwargs:通過字典形式傳遞的參數(shù)

2)post_init()

django.db.models.signals.post_init

它和pre_init可以說是一對(duì),也是作用于模型實(shí)例化時(shí),它是在__init__()之后被執(zhí)行

它有兩個(gè)參數(shù):

post_init(sender, instance)

sender:同上,創(chuàng)建實(shí)例的模型類

instance:創(chuàng)建的實(shí)例

3)pre_save()

django.db.models.signals.pre_save

在model執(zhí)行save方法前被調(diào)用

5個(gè)參數(shù):

pre_save(sender,instance,raw,using,update_fields)

sender:model類

instance:保存的實(shí)例

raw:一個(gè)Boolean類型,如果model被全部保存則為True

using:使用的數(shù)據(jù)庫別名

update_fields:傳遞的待更新的字段集合,如果沒有傳遞,則為None

4)post_save()

djang.db.models.post_save

在model執(zhí)行完save方法后被調(diào)用

6個(gè)參數(shù)

post_save(sender,instance,created,raw,using,update_fields)

sender:model class

instance:被保存的model實(shí)例

created:Boolean值,如果創(chuàng)建了一個(gè)新的記錄則為True

raw:Boolean值,如果model被全部保存則為True

using:使用的數(shù)據(jù)庫別名

update_fields:傳遞的待更新的字段集合,如果沒有傳遞,則為None

5)pre_delete()

django.db.models.signals.pre_delete

在執(zhí)行model的delete()或者queryset的delete()方法前調(diào)用

pre_delete(sender,instance,using)

sender:model class

instance:被刪除的實(shí)例

using:使用的數(shù)據(jù)庫別名

6)post_delete()

django.db.models.signals.post_delete

在執(zhí)行model的delete()或者queryset的delete()方法后調(diào)用

post_delete(sender, instance,using)

sender:model class

instance:被刪除的實(shí)例,注意:此時(shí),該實(shí)例已經(jīng)被刪除了,數(shù)據(jù)庫中不再有這條記錄,所以在使用這個(gè)實(shí)例的時(shí)候要格外注意

using:被使用的數(shù)據(jù)庫別名

7)m2m_changed()

django.db.models.signals.m2m_changed

當(dāng)一個(gè)model的ManyToManyField發(fā)生改變的時(shí)候被發(fā)送,嚴(yán)格的說,這并不是一個(gè)模型信號(hào),因?yàn)樗潜籑anyToManyField發(fā)送的,但是因?yàn)樗矊?shí)現(xiàn)了pre_save/post_save和pre_delete/post_delete,所以也在model signals中包含了。

參數(shù):

sender:描述ManyToManyField的中間模型類,這個(gè)中間模型類會(huì)在一個(gè)many-to-many字段被定義時(shí)自動(dòng)被創(chuàng)建。我們可以通過使用many-to-many字段的through屬性來訪問它

instance:被更新的多對(duì)多關(guān)系的實(shí)例。它可以是上面的sender,也可以是ManyToManyField的關(guān)系類。

action:指明作用于關(guān)系更新類型的字符串,它可以是以下幾種情況:

"pre_add"/"post_add":在向關(guān)系發(fā)送一個(gè)或多個(gè)對(duì)象前 / 后發(fā)送

"pre_remove/post_remove":從關(guān)系中刪除一個(gè)或多個(gè)對(duì)象前 / 后發(fā)送

"pre_clear/post_clear":在關(guān)系解除之前 / 之后發(fā)送

reverse:正在修改的是正向關(guān)系或者反向關(guān)系,正向False,反向?yàn)門rue

model:被添加、刪除或清除的對(duì)象的類

pk_set:對(duì)于add/remove等,pk_set是一個(gè)從關(guān)系中添加或刪除的對(duì)象的主鍵 的集合, 對(duì)于clear,pk_set為None

舉例說明:

兩個(gè)實(shí)例,且關(guān)系如下:

class Topping(models.Model):

pass

class Pizza(models.Model):


toppings = ManyToManyFields(Topping)

我們像這樣連接一個(gè)處理器

from django.db.models.signals import m2m_changed

def toppings_changed(sender, **kwargs):

pass

m2m_changed.connect(toppings_changed, sender=Pizza.toppings.through)

然后我們對(duì)上面的類做如下操作

p = Pizza.objects.create(...)

t = Topping.objects.create(...)

p.toppings.add(t)

這樣,對(duì)應(yīng)的上面的參數(shù)分別如下:

sender:描述ManyToManyField的中間類,即Pizza.toppings.through

instance:被更新的多對(duì)多關(guān)系的實(shí)例,即P(本例中,Pizza對(duì)應(yīng)被更改)

action:先是"pre_add",然后執(zhí)行上面的操作add(),最后再調(diào)用了"post_add"

reverse:本例中,Pizza包含了ManyToManyField topping,然后調(diào)用P.toppings.add(),所以這是正向更新,故reverse為False

model:被添加刪除或清除的類,本例中 Topping 被添加到Pizza

pk_set:{t.id}

我們再做下面的操作:

t.pizza_set.remove(p)

這樣,對(duì)應(yīng)的參數(shù)為:

sender:同上

instance:t(本例中,Topping實(shí)例被更改)

action:先是"pre_remove",然后執(zhí)行上面的remove,再執(zhí)行"post_remove"

reverse:True,本例中,是反向操作

model:p

pk_set:{p.id}

8)class_prepared

django.db.models.signals.class_prepared

當(dāng)模型類準(zhǔn)備好時(shí)發(fā)送,即當(dāng)模型被創(chuàng)建并注冊到Django的模型系統(tǒng)中時(shí)。

這個(gè)信號(hào)通常是在Django內(nèi)部使用,一般不會(huì)被第三方應(yīng)用使用。

2、Request/response signals

在處理請(qǐng)求時(shí)發(fā)出的信號(hào)

1)request_started()

django.core.signals.request_started

在Django開始處理HTTP請(qǐng)求時(shí)發(fā)送。

request_started(sender,environ)

2)request_finished()

django.core.signals.request_finished

在Django處理完HTTP請(qǐng)求時(shí)發(fā)送

3)got_request_exception()

django.core.signals.got_request_exception

在處理HTTP請(qǐng)求過程中遇到錯(cuò)誤時(shí)發(fā)送。

3、使用信號(hào)

1)監(jiān)聽信號(hào)

即想要接收信號(hào),可以使用Signals.connect()方法注冊一個(gè)接收器函數(shù),當(dāng)信號(hào)被發(fā)送時(shí)接收器函數(shù)被調(diào)用。

Signals.connect(receiver,sender=None,weak=True,dispatch_uid = None)

receiver:將連接到此信號(hào)的回調(diào)函數(shù)

sender:指定要接收信號(hào)的特定發(fā)送方

weak:Django默認(rèn)將信號(hào)處理程序存儲(chǔ)為弱引用。因此,如果我們的接收器是一個(gè)弱引用,那么它有可能會(huì)被垃圾回收機(jī)制給回收掉,為了防止這種情況,

我們在調(diào)用信號(hào)的connect()方法時(shí),傳遞weak=False。

dispatch_uid:給信號(hào)接收方定義的唯一標(biāo)識(shí),以防可能會(huì)有重復(fù)信號(hào)發(fā)送。

接下來以HTTP請(qǐng)求中的request_finished信號(hào)為例:

2)定義接收函數(shù)

def my_func_callback(sender, **kwargs):

print("request_finished")

如上,所有的接收函數(shù)必須要包含sender和關(guān)鍵字參數(shù)兩個(gè)參數(shù)。

3)連接接收函數(shù)

有兩種方法和將接收器和信號(hào)連接起來,我們可以選擇手動(dòng)的連接線路,如下:

from django.core.signals import request_finished

request_finished.connect(my_func_callback)

我們還可以選擇通過裝飾器來連接信號(hào)和接收器

from django.dispatch import receiver

from django.core.signals import request_finished

@receiver(request_finished)

def my_func_callback(sender, **kwargs):

pass

注意:在實(shí)踐中,信號(hào)處理程序通常定義在與他們相關(guān)的應(yīng)用程序的信號(hào)子模塊中,信號(hào)接收器連接在我們的應(yīng)用程序配置類的ready()方法中。如果使用裝飾器方式,我們只需要在reader()中導(dǎo)入signals子模塊即可。

值得一提的是,在測試過程中,我們的ready()函數(shù)可能不止一次被執(zhí)行,因此我們要保護(hù)我們的信號(hào)不要被復(fù)制。

4)連接到特定發(fā)送者發(fā)送的信號(hào)

在很多情況下,我們的信號(hào)會(huì)被多次發(fā)送,但是實(shí)際上我們只對(duì)這些信號(hào)的某個(gè)子集感興趣,例如前面收的pre_save()信號(hào)

這時(shí)候,我們可以注冊只接收特定發(fā)送者發(fā)送的信號(hào)。如下,我們可以指定我們需要接收的某個(gè)模型發(fā)送的信號(hào)

from djang.db.models.signals import pre_save

from django.dispatch import receiver

from .model import MyModel

@receiver(pre_save, sender=MyModel)

def my_receiver(sender, **kwargs):

pass

這樣,我們的my_receiver()函數(shù)將只有在MyModel被保存時(shí)被調(diào)用。

5)防止重復(fù)的信號(hào):

在某些情況下,連接接收器到信號(hào)的代碼可能會(huì)運(yùn)行多次,這可能會(huì)導(dǎo)致我們的接收器函數(shù)注冊不止一次,因此,對(duì)單個(gè)信號(hào)事件調(diào)用多次。

如我們使用信號(hào)在保存模型時(shí)發(fā)送電子郵件,則傳遞唯一標(biāo)識(shí)符作為dispatch_uid參數(shù),以識(shí)別接收函數(shù)。這個(gè)標(biāo)識(shí)符通常是一個(gè)字符串。

最終結(jié)果是,對(duì)于每個(gè)唯一的信號(hào),我們的接收器函數(shù)將只綁定到該信號(hào)一次。

from django.core.signals import request_finished

request_finished.connect(my_receiver, dispatch_uid="my_unique_identifier")

如我們注冊時(shí)保存密碼需要用到post_save,新建my_signals.py,在文件中加入下面代碼:

from django.db.models.signals import post_save

from django.dispatch import receiver

from django.contrib.auth import get_user_model

user = get_user_model()

@receiver(signal=post_save, sender=user)

def create_user(sender, instance=None, created=False, **kwarg):

password = instance.password

instance.set_password(password)

instance.save()

然后在項(xiàng)目apps中重寫ready,將我們新建的my_signals引入即可

3、自定義信號(hào)

1)定義信號(hào):

在項(xiàng)目根目錄新建文件self_signal.py

import django.dispatch

my_signal = django.dispatch.Signals(providing_args=["aaa","bbb"])

2)注冊信號(hào)(即信號(hào)接收器)

項(xiàng)目應(yīng)用下的__init__.py文件

from self_signal import my_signal

def register_my_signal(sender, **kwargs):

print("my signal msg:", sender, **kwargs)

my_signal.connect(register_my_signal)

3)觸發(fā)信號(hào)

views視圖中編寫如下:

from self_signal import my_signal

my_signal.send(sender="Python", aaa=111, bbb=2)

以上這篇基于Django signals 信號(hào)作用及用法詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python高效編程技巧

    Python高效編程技巧

    我已經(jīng)使用Python編程有多年了,即使今天我仍然驚奇于這種語言所能讓代碼表現(xiàn)出的整潔和對(duì)DRY編程原則的適用。這些年來的經(jīng)歷讓我學(xué)到了很多的小技巧和知識(shí),大多數(shù)是通過閱讀很流行的開源軟件,如Django, Flask, Requests中獲得的
    2013-01-01
  • 在python中實(shí)現(xiàn)求輸出1-3+5-7+9-......101的和

    在python中實(shí)現(xiàn)求輸出1-3+5-7+9-......101的和

    這篇文章主要介紹了在python中實(shí)現(xiàn)求輸出1-3+5-7+9-......101的和,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • 關(guān)于python的xlwings與VBA間的互相調(diào)用

    關(guān)于python的xlwings與VBA間的互相調(diào)用

    這篇文章主要介紹了關(guān)于python的xlwings與VBA間的互相調(diào)用,VBA是一種通用應(yīng)用軟件腳本語言,Excel包含和許多功能強(qiáng)大的數(shù)據(jù)分析對(duì)象,例如工作表、圖表、數(shù)據(jù)透視表以及大量的數(shù)學(xué)、財(cái)務(wù)、工程和通用業(yè)務(wù)函數(shù),配合VBA可以運(yùn)用這些對(duì)象開發(fā)出自動(dòng)程序
    2023-07-07
  • 使用python爬取B站千萬級(jí)數(shù)據(jù)

    使用python爬取B站千萬級(jí)數(shù)據(jù)

    B站我想大家都熟悉吧,其實(shí) B 站的爬蟲網(wǎng)上一搜一大堆。不過紙上得來終覺淺,絕知此事要躬行,我碼故我在。
    2018-06-06
  • Python常見庫matplotlib學(xué)習(xí)筆記之畫圖中各個(gè)模塊的含義及修改方法

    Python常見庫matplotlib學(xué)習(xí)筆記之畫圖中各個(gè)模塊的含義及修改方法

    matplotlib是python最著名的繪圖庫,它提供了一整套和matlab相似的命令A(yù)PI,十分適合交互式地進(jìn)行制圖,下面這篇文章主要給大家介紹了關(guān)于Python常見庫matplotlib學(xué)習(xí)筆記之畫圖中各個(gè)模塊的含義及修改方法的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • Python模擬登入的N種方式(建議收藏)

    Python模擬登入的N種方式(建議收藏)

    這篇文章主要介紹了Python模擬登入的N種方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • 總結(jié)Pyinstaller打包的高級(jí)用法

    總結(jié)Pyinstaller打包的高級(jí)用法

    前段時(shí)間在制作詞云制作小工具的時(shí)候,直接在命令行用pyinstaller -F 工具.py指令打包成功后,啟動(dòng)exe可執(zhí)行文件的時(shí)候各種報(bào)錯(cuò), 今天,我們就分享一下踩坑經(jīng)過,需要的朋友可以參考下
    2021-06-06
  • python scrapy爬蟲代碼及填坑

    python scrapy爬蟲代碼及填坑

    這篇文章主要介紹了python scrapy爬蟲代碼及填坑,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • python實(shí)現(xiàn)求純色彩圖像的邊框

    python實(shí)現(xiàn)求純色彩圖像的邊框

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)求純色彩圖像的邊框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • react+django清除瀏覽器緩存的幾種方法小結(jié)

    react+django清除瀏覽器緩存的幾種方法小結(jié)

    今天小編就為大家分享一篇react+django清除瀏覽器緩存的幾種方法小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07

最新評(píng)論