drf信號量


Django信號量回顧及drf信號量常用操作

一.在寫接口視圖時,保存/刪除/更新數據前后需要對序列化后的數據進行處理的方法:

  1.重寫mixins.CreateModelMixin中恩的create()函數或perform_create()函數:

    不足:代碼分離性不好,冗雜

.......   
 def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user=self.perform_create(serializer)
        re_dict=serializer.data
        payload=jwt_payload_handler(user)
        re_dict['token']=jwt_encode_handler(payload)
        re_dict['name']=user.name if user.name else user.username
        headers = self.get_success_headers(serializer.data)
        return Response(re_dict, status=status.HTTP_201_CREATED, headers=headers)

 

 def perform_create(self, serializer):
        '''
        重載CreateModelMixin中的函數實現收藏加一,也可用信號量實現(代碼分離性好)
        :param serializer:
        :return:
        '''
        instance=serializer.save()
        goods=instance.goods
        goods.fav_num+=1
        goods.save()
    def perform_destroy(self, instance):
           # 重載DestroyModelMixin中的函數實現收藏減一, 也可用信號量實現(代碼分離性好)
            instance=instance.delete()
            goods=instance.goods
            goods.fav_num-=1
            goods.save()

 

   2.信號量實現(新建signals.py在該app下方便管理):

    2.1用戶密碼更新的信號量:

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(post_save, sender=User)
def create_user(sender, instance=None, created=False, **kwargs):
#create判斷是否是新建
    if created:
        password=instance.password
        instance.set_password(password)
        instance.save()
#在app下配置信號量
from
django.apps import AppConfig class UsersConfig(AppConfig): name = 'users' verbose_name='用戶管理' #配置信號 def ready(self): import users.signals

     2.2收藏功能的信號量:

from django.db.models.signals import post_save,post_delete
from django.dispatch import receiver

from .models import UserFav


# 通過信號實現收藏加一
@receiver(post_save, sender=UserFav)
def create_userfav(sender, instance=None, created=False, **kwargs):
    if created:
        goods = instance.goods
        goods.fav_num += 1
        goods.save()


# 通過信號實現收藏減一
@receiver(post_delete, sender=UserFav)
def delete_userfav(sender, instance=None, created=False, **kwargs):
    goods = instance.goods
    goods.fav_num -= 1
    goods.save()

 

from django.apps import AppConfig


class UserOperationConfig(AppConfig):
    name = 'user_operation'
    verbose_name='用戶操作管理'

    def ready(self):
        import user_operation.signals

 二.常用信號(均通過send()方法發送)

  1.pre_init(django.db.models.signals.pre_init):

    每當您實例化Django模型時,此信號都會在模型__init__()方法的開頭發送

    使用此信號發送的參數:

    sender
    剛創建實例的模型類。
    args
    傳遞給的位置參數列表 __init__()
    kwargs
    傳遞給關鍵字參數的字典 __init__()

    例如,教程有這一行:

      p = Poll(question="What's up?", pub_date=datetime.now()) 

    發送給pre_init處理程序的參數是:

論據
sender Poll (班級本身)
args [](一個空列表,因為沒有傳遞給位置參數__init__()。)
kwargs {'question': "What's up?", 'pub_date':datetime.now()}

  2.post_init(django.db.models.signals.post_init):

    和pre_init一樣,但是這個__init__()方法方法完成時發送

    使用此信號發送的參數:

    sender
    如上所述:剛創建實例的模型類。
    instance
    剛剛創建的模型的實際實例。

  3.pre_save(django.db.models.signals.pre_save):

    這是在模型save() 方法的開頭發送的

    使用此信號發送的參數:

    sender
    模型類。
    instance
    正在保存的實際實例。
    raw
    布爾值;  True 如果模型完全按照提供的方式保存(即加載夾具時)。不應該查詢/修改數據庫中的其他記錄,因為數據庫可能尚未處於一致狀態。
    using
    正在使用的數據庫別名。
    update_fields
    要傳遞給更新的字段集 Model.save() ,或者 None  如果 update_fields 未傳遞給它 save()

  4.post_save(django.db.models.signals.post_save):

     喜歡pre_save,但在save()方法結束時發送 

     使用此信號發送的參數:

     sender
     模型類。
     instance
     正在保存的實際實例。
     created
     布爾值;  True 如果創建了新記錄。
     raw
     布爾值;  True 如果模型完全按照提供的方式保存(即加載夾具時)。不應該查詢/修改數據庫中的其他記錄,因為數據庫可能尚未處於一致狀態。
     using
     正在使用的數據庫別名。
     update_fields
    要傳遞給更新的字段集 Model.save() ,或者 None  如果 update_fields 未傳遞給它 save()

  5.pre_delete(django.db.models.signals.pre_delete)

     在模型的delete() 方法和查詢集方法的開頭發送delete()

     使用此信號發送的參數:

     sender
     模型類。
     instance
     要刪除的實際實例。
     using
     正在使用的數據庫別名。

  6.post_delete(django.db.models.signals.post_delete)

      喜歡pre_delete,但是在模型的delete()方法和查詢集方法 結束時發送 delete()

      使用此信號發送的參數:

      sender
      模型類。
      instance

      要刪除的實際實例。請注意,該對象將不再位於數據庫中,因此請謹慎對待此實例。

      using
      正在使用的數據庫別名。

  7.m2m_changed(django.db.models.signals.m2m_changed):

    ManyToManyField在模型實例上更改a 時發送嚴格來說,這不是一個模型信號,因為它是由它發送的ManyToManyField,但由於它補充了 pre_savepost_savepre_deletepost_delete 當跟蹤模型的變化時,它包含在這里。

     使用此信號發送的參數:

     sender
     中間模型類描述  ManyToManyField 定義多對多字段時,將自動創建此類; 您可以使用 through 多對多字段中屬性訪問它 
     instance
     更新多對多關系的實例。這可以是與之相關 sender 的類的實例,也可以 ManyToManyField 是與之相關的類的 實例
     action

     一個字符串,指示對關系執行的更新類型。這可以是以下之一:

  "pre_add"

     在將一個或多個對象添加到關系之前發送。

  "post_add"

        將一個或多個對象添加到關系后發送。

  "pre_remove"

        在從關系中刪除一個或多個對象之前發送。

  "post_remove"

        從關系中刪除一個或多個對象發送

  "pre_clear"

       在清除關系之前發送。

  "post_clear"

       關系清除后發送。

     reverse

              指示關系的哪一側被更新(即,是否正在被修改的正向或反向關系)。

     model

               從關系中添加,刪除或清除的對象類。

     pk_set

       對於pre_addpost_addpre_removepost_remove 的動作,這是一組已被添加到或從關系移除主鍵值。

     對於pre_clearpost_clear行動,這是None

     using

    正在使用的數據庫別名。

  8.classprepared(django.db.models.signals.class_prepared)

     每當模型類被“准備好”時發送 - 也就是說,一旦定義了模型並使用Django的模型系統注冊了模型。Django在內部使用這個信號; 它通常不用於第三方應用程序。

     由於此信號在app注冊表填充過程中發送,並 AppConfig.ready()在app注冊表完全填充后運行,因此無法在該方法中連接接收器。一種可能性是連接它們AppConfig.__init__(),注意不要導入模型或觸發對app注冊表的調用。

     使用此信號發送的參數:

     sender
     剛准備的模型類。

三.管理信號(django-admin發送的信號)

  1.pre_migrate(django.db.models.signals.pre_migrate):

     migrate在開始安裝應用程序之前命令發送對於缺少models模塊的應用程序,它不會發出

     使用此信號發送的參數:

     sender
    AppConfig 要遷移/同步的應用程序實例。
     app_config
    與...相同 sender
     verbosity

    指示manage.py在屏幕上打印的信息量。請參閱--verbosity旗幟了解詳情。

    偵聽的函數pre_migrate應根據此參數的值調整它們輸出到屏幕的內容。

     interactive

    如果interactiveTrue,則提示用戶在命令行上輸入內容是安全的。如果interactiveFalse,偵聽此信號的功能不應嘗試提示任何內容。

    例如,django.contrib.auth應用程序只提示,當創建一個超級用戶interactiveTrue

     using
     命令將在其上運行的數據庫的別名。
     plan
     Django 1.10中的新功能。

    將用於遷移運行的遷移計划。雖然該計划不是公共API,但這允許在必要時了解計划的極少數情況。計划是兩元組的列表,第一項是遷移類的實例,第二項顯示遷移是回滾(True)還是應用(False)。

     apps
    Django 1.10中的新功能。

    Apps在遷移運行之前包含項目狀態的實例應該使用它來代替全局 apps注冊表來檢索要對其執行操作的模型。

 

2.post_migrate(django.db.models.signals.post_migrate):

   在結束時發送migrate(即使沒有運行遷移)和 flush命令。對於缺少models模塊的應用程序,它不會發出 

   此信號的處理程序不得執行數據庫模式更改,因為這樣做可能會導致flush命令在migrate命令期間運行時失敗 

   使用此信號發送的參數:

   sender
    AppConfig 剛剛安裝的應用程序實例。
   app_config
    與...相同 sender
   verbosity

    指示manage.py在屏幕上打印的信息量。請參閱--verbosity旗幟了解詳情。

    偵聽的函數post_migrate應根據此參數的值調整它們輸出到屏幕的內容。

   interactive

    如果interactiveTrue,則提示用戶在命令行上輸入內容是安全的。如果interactiveFalse,偵聽此信號的功能不應嘗試提示任何內容。

    例如,django.contrib.auth應用程序只提示,當創建一個超級用戶interactiveTrue

   using
   用於同步的數據庫別名。默認為 default  數據庫。
   plan
    Django 1.10中的新功能。

    用於遷移運行的遷移計划。雖然該計划不是公共API,但這允許在必要時了解計划的極少數情況。計划是兩元組的列表,第一項是遷移類的實例,第二項顯示遷移是回滾(True)還是應用(False)。

   apps
    Django 1.10中的新功能。

    Apps遷移運行后包含項目狀態的實例應該使用它來代替全局 apps注冊表來檢索要對其執行操作的模型。

   例如,您可以在此處注冊回調 AppConfig

from django.apps import AppConfig
from django.db.models.signals import post_migrate

def my_callback(sender, **kwargs):
    # Your specific logic here
    pass

class MyAppConfig(AppConfig):
    ...

    def ready(self):
        post_migrate.connect(my_callback, sender=self)

    注意:如果您提供AppConfig實例作為sender參數,請確保信號已注冊 ready()AppConfig對於使用修改集INSTALLED_APPS(例如,當覆蓋設置時)運行的測試,將重新創建s,並且應為每個新AppConfig實例連接此類信號。

四.請求/響應信號(處理請求時核心框架發出的信號)

  1.request_started(django.core.signals.request_started):

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

     使用此信號發送的參數:

     sender
     處理程序類 - 例如 django.core.handlers.wsgi.WsgiHandler- 處理請求。

     environ

    environ提供給請求的字典。

2.request_finished(django.core.signals.request_finished):

   當Django完成向客戶端發送HTTP響應時發送。

   使用此信號發送的參數:

  sender

       處理程序類,如上所述。

3.got_request_exception(django.core.signals.got_request_exception):

   只要Django在處理傳入的HTTP請求時遇到異常,就會發送此信號。

  使用此信號發送的參數:

  sender

       處理程序類,如上所述。

  request

      HttpRequest對象。 

五.測試信號(僅在運行測試時發送的信號)

  1.setting_changed(django.test.signals.setting_changed):

    當通過django.test.TestCase.settings()上下文管理器或 django.test.override_settings()裝飾器/上下文管理器更改設置的值時,將發送此信號 。

    它實際上發送了兩次:當應用新值(“設置”)和恢復原始值(“拆除”)時。使用enter參數來區分這兩者。

    您也可以從中導入此信號,django.core.signals以避免django.test在非測試情況下導入。

    使用此信號發送的參數:

    sender
    設置處理程序。
    setting
    設置的名稱。
    value
    更改后的設置值。對於最初不存在的設置,在“拆卸”階段, valueNone
    enter
    布爾值;  True如果應用該設置, False則恢復。

  2.template_rendered(django.test.signals.template_rendered)

 在測試系統呈現模板時發送。在Django服務器的正常操作期間不會發出此信號 - 它僅在測試期間可用。

   使用此信號發送的參數:

 sender
  Template呈現的對象。
 template
      與發件人相同
 context
      在 Context與該模板被渲染。

 

六.數據庫包裝器(啟動數據庫連接時由數據庫包裝程序發送的信號)

  1.connection_created(django.db.backends.signals.connection_created):

    數據庫包裝器與數據庫建立初始連接時發送。如果您要將任何后連接命令發送到SQL后端,這將特別有用。

    使用此信號發送的參數:

    sender

        數據庫包裝類 - 即 django.db.backends.postgresql.DatabaseWrapperdjango.db.backends.mysql.DatabaseWrapper

    connection

        已打開的數據庫連接。這可以在多數據庫配置中使用,以區分來自不同數據庫的連接信號。

 

七.詳情官方文檔:

  二到六均摘抄於官方文檔,更多具體內容:

              https://docs.djangoproject.com/en/1.11/ref/signals/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM