Django 的信号 & Flask 的信号

信号:框架内部已帮助开发者预留的可扩展的位置

一、Django 的信号

项目目录结构:

django_signal
|--- app01
    |--- models.py
    |--- views.py
    ...
|--- django_signal
    |--- __init__.py
    |--- urls.py
    ...
|--- manage.py

 

django_signal/django_signal/urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^func1/', views.func1),
    url(r'^func2/', views.func2),
    url(r'^func3/', views.func3),
    url(r'^func4/', views.func4),
]

 

django_signal/django_signal/__init__.py

# 程序刚启动起来的时候,该py文件会先执行,所以信号写在了该文件中

from django.db.models import signals

def before_save1(*args,**kwargs):  # 发送的信号的内容(signals.pre_save 的)
    print('有车来了,我要服务了--》',args,kwargs)

def before_save2(*args,**kwargs):
    print('有车来了,我要服务了--》',args,kwargs)

def after_save1(*args,**kwargs):
    print('有车来了,完事了--》',args,kwargs)

signals.pre_save.connect(before_save1)  # signals.pre_save : 数据库ORM 保存之前 的信号; .connect() 中放函数(如数据库增加之前想要做的操作); 这行代码的含义:把 before_save1 这个函数注册到了 signals.pre_save 这个信号中
signals.pre_save.connect(before_save2)  # 也是数据库保存之前的信号:数据库增加和更新之前会执行(内部用 .save()来触发的)

signals.post_save.connect(after_save1)  # 数据库保存之后进行的操作的信号



"""
Django 的内置信号:
Model signals
    pre_init                    # django的modal执行其构造方法前,自动触发
    post_init                   # django的modal执行其构造方法后,自动触发
    pre_save                    # django的modal对象保存前,自动触发
    post_save                   # django的modal对象保存后,自动触发
    pre_delete                  # django的modal对象删除前,自动触发
    post_delete                 # django的modal对象删除后,自动触发
    m2m_changed                 # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
    class_prepared              # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
Management signals
    pre_migrate                 # 执行migrate命令前,自动触发
    post_migrate                # 执行migrate命令后,自动触发
Request/response signals
    request_started             # 请求到来前,自动触发
    request_finished            # 请求结束后,自动触发
    got_request_exception       # 请求异常后,自动触发
Test signals
    setting_changed             # 使用test测试修改配置文件时,自动触发
    template_rendered           # 使用test测试渲染模板时,自动触发
Database Wrappers
    connection_created          # 创建数据库连接时,自动触发
"""

 

django_signal/app01/modles.py

from django.db import models

class User(models.Model):

    title = models.CharField(max_length=32)

 

django_signal/app01/views.py

from django.shortcuts import render,HttpResponse
from app01 import models

def func1(request):
    # 该视图没有数据库修改的操作,所以请求通过该视图时不会触发 信号
    return HttpResponse('创建成功')

def func2(request):
    models.User.objects.create(title='小男孩')
    return HttpResponse('创建成功')

def func3(request):
    models.User.objects.create(title='小少年')
    return HttpResponse('创建成功')

def func4(request):
    models.User.objects.create(title='小青年')
    return HttpResponse('创建成功')

 

二、Flask 的信号

1. 安装第三方组件:blinker

pip install blinker

 

示例代码:

from flask import Flask,render_template
from flask import signals

app = Flask(__name__)

def x1(arg):
    print('x1')
def x2(arg):
    print('x2')
signals.request_started.connect(x1)  # signals.request_started : 请求刚开始时触发的信号 
signals.request_started.connect(x2)


@app.before_request
def bf():
    print('bbbbb')
    return render_template("asdfadf")


@app.route('/index')
def func():
    print('视图函数')
    return "asdfasdf"


if __name__ == '__main__':
    # app.__call__
    app.run()
    # with app.app_context():
    #     pass


"""
Flask 的内置信号:
request_started = _signals.signal('request-started')                # 请求到来前执行
request_finished = _signals.signal('request-finished')              # 请求结束后执行
 
before_render_template = _signals.signal('before-render-template')  # 模板渲染前执行
template_rendered = _signals.signal('template-rendered')            # 模板渲染后执行
 
got_request_exception = _signals.signal('got-request-exception')    # 请求执行出现异常时执行
 
request_tearing_down = _signals.signal('request-tearing-down')      # 请求执行完毕后自动执行(无论成功与否)
appcontext_tearing_down = _signals.signal('appcontext-tearing-down')# 应用上下文执行完毕后自动执行(无论成功与否)
 
appcontext_pushed = _signals.signal('appcontext-pushed')            # 应用上下文push时执行
appcontext_popped = _signals.signal('appcontext-popped')            # 应用上下文pop时执行
message_flashed = _signals.signal('message-flashed')                # 调用flask在其中添加数据时,自动触发
"""

# 由于Flask本身没有ORM,所以Flask没有数据库相关的信号;它只有一些Flask内置的信号,如 请求走到哪儿时的信号

"""
signals.request_started 的信号 在 before_request 这个装饰器 之前执行;
被 before_request 装饰的函数可以有返回值,并且能够拦截请求;但信号拦截不了请求,请求只能穿过信号(信号的返回值不影响请求的流程)
"""

 

posted @ 2019-02-13 22:25  neozheng  阅读(305)  评论(0编辑  收藏  举报