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/

drf信号量的更多相关文章

  1. DRF 商城项目 - 用户( 登录, 注册,登出,个人中心 ) 逻辑梳理

    用户登录 自定义用户登录字段处理 用户的登录时通过 手机号也可以进行登录 需要重写登录验证逻辑 from django.contrib.auth.backends import ModelBacken ...

  2. ucos实时操作系统学习笔记——任务间通信(信号量)

    ucos实时操作系统的任务间通信有好多种,本人主要学习了sem, mutex, queue, messagebox这四种.系统内核代码中,这几种任务间通信机制的实现机制相似,接下来记录一下本人对核心代 ...

  3. Linux 信号量详解一

    信号量主要用于进程间(不是线程)的互斥,通过sem_p()函数加锁使用资源,sem_v函数解锁释放资源,在加锁期间,CPU从硬件级别关闭中断,防止pv操作被打断. semget函数 int semge ...

  4. PHP进程通信基础——信号量+共享内存通信

    PHP进程通信基础--信号量+共享内存通信 由于进程之间谁先执行并不确定,这取决于内核的进程调度算法,其中比较复杂.由此有可能多进程在相同的时间内同时访问共享内存,从而造成不可预料的错误.信号量这个名 ...

  5. C#多线程--信号量(Semaphore)

    百度百科:Semaphore,是负责协调各个线程, 以保证它们能够正确.合理的使用公共资源.也是操作系统中用于控制进程同步互斥的量. Semaphore常用的方法有两个WaitOne()和Releas ...

  6. Linux学习笔记(15)-信号量

    在多线程或者多进程编程中,有一个非常需要关注的东西,那就是同步以及互斥问题. 同步是指多个进程之间的协作,而互斥是指多个进程之间,为了争夺有限的资源,而进行的竞争. 理论很高端,但经过自己几天的学习, ...

  7. 多线程之信号量(By C++)

    信号量在多线程中,主要是用于线程的同步或者限制线程运行的数量. 所谓同步,当流程1运行在线程1中,流程2运行在线程2中,流程2必须在流程1结束之后才能开始执行.你会怎么做,所有就需要给出一个流程1结束 ...

  8. 信号量sem

    一.什么是信号量 为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域.临界区域是指执行数据更 ...

  9. 【.NET深呼吸】线程信号量(Semaphore)

    Semaphore类可以控制某个资源允许访问的线程数,Semaphore有命名式的,也有不命名的:如果不考虑跨进程工作,一般在代码中使用不命名方式即可. 信号量有点类似于等待句柄,某个线程如果调用了W ...

随机推荐

  1. 【转】Win10开机密码忘了?教你破解Win10开机密码

    [PConline 技巧]Win10开机密码忘记了怎么办?这个问题很多人都遇到过,如何破解一台Win10电脑的开机密码呢(非BIOS开机密码)?其实很简单,利用下面这个方法,分分钟就能搞定. 一招破解 ...

  2. 【移动端】icon中ng-cordova使用

    cordova介绍 Cordova提供了一组设备相关的API,通过这组API,移动应用能够以JavaScript访问原生的设备功能,如摄像头.麦克风等. Cordova支持如下7种移动操作系统:iOS ...

  3. (0)HomeAssistant 教程

    国外:https://www.home-assistant.io/components/light.mqtt/ 中国:https://www.hachina.io/docs/890.html

  4. ActiveMQ 控制台使用方法

    一.为什么使用ActiveMQ 在总线的设计中可能会使用到JMS(Java Message Service)通道, Java消息服务(JMS)超越了生产商专有的MOM(Message-Oriented ...

  5. 深度学习框架PyTorch一书的学习-第三章-Tensor和autograd-1-Tensor

    参考https://github.com/chenyuntc/pytorch-book/tree/v1.0 希望大家直接到上面的网址去查看代码,下面是本人的笔记 Tensor Tensor可以是一个数 ...

  6. docker 4 docker的三要素

    docker三要素 镜像,容器,仓库 镜像 docker镜像(image)就是一个只读的模板,镜像可以用来创建docker容器,一个镜像可以创建很多个容器 容器 docker利用容器(containe ...

  7. 浅谈文件断点续传和WebUploader的基本结合

    0.写在前面的话 上篇博客已经是在8月了,期间到底发生了什么,只有我自己知道,反正就是心情特别糟糕,生活状态工作状态学习状态都十分不好,还有心思进取吗,No!现在状态好起来了,生活又充满了希望 :D  ...

  8. python内建的命名空间研究

    python内建的命名空间研究 说明: python内置模块的命名空间.python在启动的时候会自动为我们载入很多内置的函数.类,比如 dict,list,type,print,这些都位于 __bu ...

  9. UIImageView - BNR

    继续上节UINavigationController - BNR. 打开BNRDetailViewController.xib文件,向view中添加UIImageView对象,选中该对象,通过Attr ...

  10. adb命令集合

    1. 获取序列号: adb get-serialno 2. 查看连接计算机的设备: adb devices 3. 重启机器: adb reboot 4. 重启到bootloader,即刷机模式: ad ...