中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

基于Django signals信號有什么用

發布時間:2021-05-27 11:37:13 來源:億速云 閱讀:163 作者:小新 欄目:開發技術

這篇文章主要介紹了基于Django signals信號有什么用,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

1、Model signals

django.db.models.signales 作用于django的model操作上的一系列信號

1)pre_init()

django.db.models.signals.pre_init

當模型實例化時調用,在__init__()之前執行

三個參數:

pre_init(sender, args, kwargs):

sender:創建實例的模型類

args:參數列表

kwargs:通過字典形式傳遞的參數

2)post_init()

django.db.models.signals.post_init

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

它有兩個參數:

post_init(sender, instance)

sender:同上,創建實例的模型類

instance:創建的實例

3)pre_save()

django.db.models.signals.pre_save

在model執行save方法前被調用

5個參數:

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

sender:model類

instance:保存的實例

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

using:使用的數據庫別名

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

4)post_save()

djang.db.models.post_save

在model執行完save方法后被調用

6個參數

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

sender:model class

instance:被保存的model實例

created:Boolean值,如果創建了一個新的記錄則為True

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

using:使用的數據庫別名

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

5)pre_delete()

django.db.models.signals.pre_delete

在執行model的delete()或者queryset的delete()方法前調用

pre_delete(sender,instance,using)

sender:model class

instance:被刪除的實例

using:使用的數據庫別名

6)post_delete()

django.db.models.signals.post_delete

在執行model的delete()或者queryset的delete()方法后調用

post_delete(sender, instance,using)

sender:model class

instance:被刪除的實例,注意:此時,該實例已經被刪除了,數據庫中不再有這條記錄,所以在使用這個實例的時候要格外注意

using:被使用的數據庫別名

7)m2m_changed()

django.db.models.signals.m2m_changed

當一個model的ManyToManyField發生改變的時候被發送,嚴格的說,這并不是一個模型信號,因為它是被ManyToManyField發送的,但是因為它也實現了pre_save/post_save和pre_delete/post_delete,所以也在model signals中包含了。

參數:

sender:描述ManyToManyField的中間模型類,這個中間模型類會在一個many-to-many字段被定義時自動被創建。我們可以通過使用many-to-many字段的through屬性來訪問它

instance:被更新的多對多關系的實例。它可以是上面的sender,也可以是ManyToManyField的關系類。

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

"pre_add"/"post_add":在向關系發送一個或多個對象前 / 后發送

"pre_remove/post_remove":從關系中刪除一個或多個對象前 / 后發送

"pre_clear/post_clear":在關系解除之前 / 之后發送

reverse:正在修改的是正向關系或者反向關系,正向False,反向為True

model:被添加、刪除或清除的對象的類

pk_set:對于add/remove等,pk_set是一個從關系中添加或刪除的對象的主鍵 的集合, 對于clear,pk_set為None

舉例說明:

兩個實例,且關系如下:

class Topping(models.Model):

pass

class Pizza(models.Model):


toppings = ManyToManyFields(Topping)

我們像這樣連接一個處理器

from django.db.models.signals import m2m_changed

def toppings_changed(sender, **kwargs):

pass

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

然后我們對上面的類做如下操作

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

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

p.toppings.add(t)

這樣,對應的上面的參數分別如下:

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

instance:被更新的多對多關系的實例,即P(本例中,Pizza對應被更改)

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

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

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

pk_set:{t.id}

我們再做下面的操作:

t.pizza_set.remove(p)

這樣,對應的參數為:

sender:同上

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

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

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

model:p

pk_set:{p.id}

8)class_prepared

django.db.models.signals.class_prepared

當模型類準備好時發送,即當模型被創建并注冊到Django的模型系統中時。

這個信號通常是在Django內部使用,一般不會被第三方應用使用。

2、Request/response signals

在處理請求時發出的信號

1)request_started()

django.core.signals.request_started

在Django開始處理HTTP請求時發送。

request_started(sender,environ)

2)request_finished()

django.core.signals.request_finished

在Django處理完HTTP請求時發送

3)got_request_exception()

django.core.signals.got_request_exception

在處理HTTP請求過程中遇到錯誤時發送。

3、使用信號

1)監聽信號

即想要接收信號,可以使用Signals.connect()方法注冊一個接收器函數,當信號被發送時接收器函數被調用。

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

receiver:將連接到此信號的回調函數

sender:指定要接收信號的特定發送方

weak:Django默認將信號處理程序存儲為弱引用。因此,如果我們的接收器是一個弱引用,那么它有可能會被垃圾回收機制給回收掉,為了防止這種情況,

我們在調用信號的connect()方法時,傳遞weak=False。

dispatch_uid:給信號接收方定義的唯一標識,以防可能會有重復信號發送。

接下來以HTTP請求中的request_finished信號為例:

2)定義接收函數

def my_func_callback(sender, **kwargs):

print("request_finished")

如上,所有的接收函數必須要包含sender和關鍵字參數兩個參數。

3)連接接收函數

有兩種方法和將接收器和信號連接起來,我們可以選擇手動的連接線路,如下:

from django.core.signals import request_finished

request_finished.connect(my_func_callback)

我們還可以選擇通過裝飾器來連接信號和接收器

from django.dispatch import receiver

from django.core.signals import request_finished

@receiver(request_finished)

def my_func_callback(sender, **kwargs):

pass

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

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

4)連接到特定發送者發送的信號

在很多情況下,我們的信號會被多次發送,但是實際上我們只對這些信號的某個子集感興趣,例如前面收的pre_save()信號

這時候,我們可以注冊只接收特定發送者發送的信號。如下,我們可以指定我們需要接收的某個模型發送的信號

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()函數將只有在MyModel被保存時被調用。

5)防止重復的信號:

在某些情況下,連接接收器到信號的代碼可能會運行多次,這可能會導致我們的接收器函數注冊不止一次,因此,對單個信號事件調用多次。

如我們使用信號在保存模型時發送電子郵件,則傳遞唯一標識符作為dispatch_uid參數,以識別接收函數。這個標識符通常是一個字符串。

最終結果是,對于每個唯一的信號,我們的接收器函數將只綁定到該信號一次。

from django.core.signals import request_finished

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

如我們注冊時保存密碼需要用到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()

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

基于Django signals信號有什么用

3、自定義信號

1)定義信號:

在項目根目錄新建文件self_signal.py

import django.dispatch

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

2)注冊信號(即信號接收器)

項目應用下的__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)觸發信號

views視圖中編寫如下:

from self_signal import my_signal

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

感謝你能夠認真閱讀完這篇文章,希望小編分享的“基于Django signals信號有什么用”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

长白| 墨玉县| 图片| 屯留县| 深水埗区| 广河县| 郧西县| 建平县| 武功县| 株洲市| 卓尼县| 广平县| 竹溪县| 正安县| 卓资县| 德清县| 乐山市| 巴彦淖尔市| 永春县| 英山县| 平远县| 辰溪县| 梅州市| 沂南县| 万年县| 长海县| 高邑县| 韩城市| 札达县| 宁南县| 九龙县| 井冈山市| 柘城县| 稻城县| 宁海县| 凉山| 读书| 云浮市| 无极县| 永泰县| 杂多县|