• 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/

  • 相关阅读:
    STL之map UVa156
    STL之vector UVa101
    STL之set UVa10815
    无修改区间查询 BNU Can you answer these queries I
    区间修改点查询 HDU1556
    无废话ExtJs 入门教程九[数字字段:NumberField、隐藏字段Hidden、日期字段:DataFiedl]
    无废话ExtJs 入门教程七[登陆窗体Demo:Login]
    无废话ExtJs 入门教程六[按钮:Button]
    无废话ExtJs 入门教程五[文本框:TextField]
    无废话ExtJs 入门教程四[表单:FormPanel]
  • 原文地址:https://www.cnblogs.com/lyq-biu/p/9698176.html
Copyright © 2020-2023  润新知