成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

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

基于Django signals 信號作用及用法詳解

瀏覽:8日期:2024-10-17 13:54:18

1、Model signals

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

1)pre_init()

django.db.models.signals.pre_init

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

三個參數(shù):

pre_init(sender, args, kwargs):

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

args:參數(shù)列表

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

2)post_init()

django.db.models.signals.post_init

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

它有兩個參數(shù):

post_init(sender, instance)

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

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

3)pre_save()

django.db.models.signals.pre_save

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

5個參數(shù):

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

sender:model類

instance:保存的實例

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

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

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

4)post_save()

djang.db.models.post_save

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

6個參數(shù)

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

sender:model class

instance:被保存的model實例

created:Boolean值,如果創(chuàng)建了一個新的記錄則為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:被刪除的實例

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:被刪除的實例,注意:此時,該實例已經(jīng)被刪除了,數(shù)據(jù)庫中不再有這條記錄,所以在使用這個實例的時候要格外注意

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

7)m2m_changed()

django.db.models.signals.m2m_changed

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

參數(shù):

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

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

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

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

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

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

reverse:正在修改的是正向關(guān)系或者反向關(guān)系,正向False,反向為True

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

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

舉例說明:

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

class Topping(models.Model):passclass Pizza(models.Model):toppings = ManyToManyFields(Topping)

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

from django.db.models.signals import m2m_changeddef toppings_changed(sender, **kwargs):passm2m_changed.connect(toppings_changed, sender=Pizza.toppings.through)

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

p = Pizza.objects.create(...)t = Topping.objects.create(...)p.toppings.add(t)

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

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

instance:被更新的多對多關(guān)系的實例,即P(本例中,Pizza對應(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)

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

sender:同上

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

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)備好時發(fā)送,即當(dāng)模型被創(chuàng)建并注冊到Django的模型系統(tǒng)中時。

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

2、Request/response signals

在處理請求時發(fā)出的信號

1)request_started()

django.core.signals.request_started

在Django開始處理HTTP請求時發(fā)送。

request_started(sender,environ)

2)request_finished()

django.core.signals.request_finished

在Django處理完HTTP請求時發(fā)送

3)got_request_exception()

django.core.signals.got_request_exception

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

3、使用信號

1)監(jiān)聽信號

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

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

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

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

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

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

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

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

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

def my_func_callback(sender, **kwargs):

print('request_finished')

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

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

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

from django.core.signals import request_finished

request_finished.connect(my_func_callback)

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

from django.dispatch import receiverfrom django.core.signals import request_finished@receiver(request_finished)def my_func_callback(sender, **kwargs):pass

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

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

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

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

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

from djang.db.models.signals import pre_savefrom django.dispatch import receiverfrom .model import MyModel@receiver(pre_save, sender=MyModel)def my_receiver(sender, **kwargs):pass

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

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

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

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

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

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_savefrom django.dispatch import receiverfrom django.contrib.auth import get_user_modeluser = get_user_model()@receiver(signal=post_save, sender=user)def create_user(sender, instance=None, created=False, **kwarg):password = instance.passwordinstance.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)注冊信號(即信號接收器)

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

from self_signal import my_signaldef register_my_signal(sender, **kwargs):print('my signal msg:', sender, **kwargs)my_signal.connect(register_my_signal)

3)觸發(fā)信號

views視圖中編寫如下:

from self_signal import my_signal

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

以上這篇基于Django signals 信號作用及用法詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Django
相關(guān)文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
一区二区三区四区国产精品| 欧美大片日本大片免费观看| 欧洲精品中文字幕| 国产乱码精品一区二区三| 久久精品一区二区三区不卡 | 久久精品盗摄| 色综合亚洲欧洲| 另类小说图片综合网| 国产精品少妇自拍| 日韩一区二区在线播放| 久久精品一区| 夜夜嗨av一区二区三区网站四季av| 成人av一区二区三区| 蜜臀av性久久久久蜜臀aⅴ四虎| 日韩视频免费观看高清完整版| 亚洲一区二区四区| 亚洲经典在线| 国内精品美女在线观看| 国产成人精品一区二| 亚洲h动漫在线| 国产欧美一区二区精品性| 欧美日韩成人在线一区| 国产精品一区在线播放| 欧美 日韩 国产在线| 国产精品香蕉一区二区三区| 五月综合激情日本mⅴ| 亚洲欧美日韩国产一区二区三区| 91精品国产黑色紧身裤美女| 久久一区二区三区超碰国产精品| 欧美在线日韩精品| 国产一区二区毛片| 国产一区二区三区综合| 老鸭窝一区二区久久精品| 亚洲一区二区黄色| 亚洲欧美一区二区三区久本道91| 国产女同性恋一区二区| 国产日韩欧美精品一区| 久久新电视剧免费观看| 日韩手机在线导航| 日韩美女一区二区三区四区| 91精品福利在线一区二区三区| 欧美丰满高潮xxxx喷水动漫| 欧美日韩第一区日日骚| 日韩一区二区影院| 精品剧情v国产在线观看在线| 91精品国产福利在线观看 | 日韩经典中文字幕一区| 亚洲综合色视频| 日韩成人免费看| 精品在线播放免费| 国产.精品.日韩.另类.中文.在线.播放| 国产麻豆精品在线观看| 国产69精品久久久久毛片| 97精品超碰一区二区三区| 色综合网站在线| 欧美日一区二区三区在线观看国产免| 国模吧视频一区| 欧美日韩国产亚洲一区| 在线看片成人| 麻豆9191精品国产| 91精品久久久久久蜜臀| 国产欧美日韩视频在线观看| 亚洲色图欧美激情| 免费看欧美美女黄的网站| 国产精品一区二区三区网站| 91在线视频播放| 欧美久色视频| 国产亚洲欧美一区二区三区| 欧美日韩免费不卡视频一区二区三区 | 欧洲精品在线观看| 91精品在线免费| 亚洲精品在线三区| 国产精品久久久久一区二区三区| 亚洲精品国产无套在线观| 亚洲成人综合视频| 国产乱人伦偷精品视频不卡| 99国产欧美久久久精品| 99视频日韩| 91精品国模一区二区三区| 日本一区二区视频在线| 人妖欧美一区二区| 99国内精品久久| 91官网在线观看| 精品成人佐山爱一区二区| 亚洲一区二区三区四区五区中文| 狠狠色丁香久久婷婷综| 99re6这里只有精品视频在线观看 99re8在线精品视频免费播放 | 国产大陆a不卡| 欧美三级网页| 色噜噜久久综合| 精品国精品国产| 欧美aaa在线| 亚洲手机在线| 91精品国产欧美一区二区 | av成人天堂| 欧美精品三级在线观看| 国产精品色哟哟网站| 精品视频一区二区三区免费| 欧美高清一区二区| 美洲天堂一区二卡三卡四卡视频 | 精品日韩一区二区| 亚洲va欧美va天堂v国产综合| 91网页版在线| 色婷婷久久久久swag精品| 中文字幕二三区不卡| 国产精品综合视频| 毛片一区二区| 中文字幕在线观看一区| 老司机免费视频一区二区三区| 在线精品一区| 久久久美女艺术照精彩视频福利播放| 日韩国产成人精品| 亚洲免费大片| 国产精品色哟哟网站| 国产91色综合久久免费分享| 欧洲精品一区二区| 亚洲欧洲综合另类| 欧美色图首页| 亚洲国产成人私人影院tom| 懂色av噜噜一区二区三区av| 91精彩视频在线| 亚洲超丰满肉感bbw| 午夜综合激情| 亚洲美女免费视频| 在线成人亚洲| 亚洲男同1069视频| 在线视频一区观看| 99精品久久免费看蜜臀剧情介绍| 国产情人综合久久777777| 久久99久久久久| 国产偷自视频区视频一区二区| 亚洲私拍自拍| 欧美酷刑日本凌虐凌虐| www国产成人免费观看视频 深夜成人网| 亚洲一区二区三区在线| 精品一区二区免费在线观看| 九九热在线视频观看这里只有精品| 91久久香蕉国产日韩欧美9色| 亚洲国产精品一区二区久久| 国产成人精品免费一区二区| 亚洲视频久久| 亚洲桃色在线一区| 久久精品人人| 国产精品九色蝌蚪自拍| 91视频xxxx| 中文字幕欧美日韩一区| 99r国产精品| 首页国产丝袜综合| 国产欧美精品区一区二区三区| 日韩久久久精品| 91精品国产综合久久香蕉麻豆| 欧美系列日韩一区| 久久综合电影| 国产精品久久国产三级国电话系列| 欧美日韩一区在线视频| 99re6这里只有精品视频在线观看| 粉嫩高潮美女一区二区三区| 久久成人麻豆午夜电影| 免费观看一级欧美片| 亚洲成人tv网| 亚洲一二三四久久| 玉米视频成人免费看| 亚洲乱码中文字幕| 综合av第一页| 国产精品夫妻自拍| 国产精品国模大尺度视频| 国产欧美一区二区精品秋霞影院| 久久久影视传媒| 久久午夜免费电影| 久久影院视频免费| 2024国产精品| 26uuu亚洲综合色欧美 | 在线亚洲高清视频| 在线免费av一区| 欧美亚洲高清一区| 欧美三区在线观看| 欧美日韩一本到| 宅男在线国产精品| 日韩免费高清电影| 久久精品一区八戒影视| 亚洲国产精品国自产拍av| 欧美极品另类videosde| 久久精品夜色噜噜亚洲a∨| 国产日韩av一区| 国产精品视频一二| 国产精品进线69影院| 亚洲精品中文在线| 亚瑟在线精品视频| 六月婷婷色综合| 国产精品99久久久| 99re成人在线| 黄色成人在线网址| 国产欧美精品| 色婷婷精品久久二区二区蜜臂av| 欧美性猛交一区二区三区精品| 欧美日韩美女一区二区| 欧美一区二区三区视频免费| 欧美一区二区三区视频免费播放| 精品福利在线导航| 18成人在线视频|