flask_信号,,内置信号使用--末班渲染前-记录日志,,自定义信号,,django中信号的使用,,sqlalchemy快速使用,,原生操作,,操作表
# Flask框架中的信号基于blinker,其主要就是让开发者可是在flask请求过程中定制一些用户行为 # signal: 信号 翻译过来的 让开发者可是在flask请求过程中定制一些用户行为 # semaphore :信号量 并发编程,信号量---锁 锁,多把锁 # 内置信号--》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在其中添加数据时,自动触发 # 自定义信号
from flask import Flask, render_template app = Flask(__name__) app.debug = True ### 我们现在想在模板渲染之 : 记录日志 使用内置信号实现 # 1 写一个函数 def before_render(*args, **kwargs): print(args) print(kwargs) # 谁(ip) 在什么时间 访问了哪个页面(template) print('记录日志,模板要渲染了') # 2 跟内置信号绑定 from flask.signals import before_render_template before_render_template.connect(before_render) # 3 源码中触发信号执行(我们不需要动) # before_render_template.send() 源码再模板渲染之前,它写死了 @app.route('/') def index(): return render_template('index.html') @app.route('/login') def login(): return render_template('login.html') if __name__ == '__main__': app.run()
from flask import Flask, render_template from flask.signals import _signals import pymysql app = Flask(__name__) app.debug = True # 1 定义信号 # 自定义信号 db_save = _signals.signal('db_save') # 2 写一个函数 def db_save_fun(*args, **kwargs): print(args) print(kwargs) print('表数据插入了') # 3 跟自定义置信号绑定 db_save.connect(db_save_fun) # 3 触发信号执行(需要我们做) # before_render_template.send() 源码再模板渲染之前,它写死了 @app.route('/') def index(): return render_template('index.html') @app.route('/create_article') def create_article(): conn = pymysql.connect(host='127.0.0.1', user='root', password='1234', database='cnblogs') cursor = conn.cursor() cursor.execute('insert into article (title,author) VALUES (%s,%s)', args=['测试测试标题', '测试作者测试']) conn.commit() # 手动触发信号 db_save.send(table_name='article',info={'title':'测试测试标题','author':'测试作者测试'}) return '插入成功' if __name__ == '__main__': app.run() # 步骤: # 1 定义信号 db_save = _signals.signal('db_save') # 2 写一个函数 def db_save_fun(*args, **kwargs): print(args) print(kwargs) print('表数据插入了') # 3 跟自定义置信号绑定 db_save.connect(db_save_fun) # 3 触发信号执行(需要我们做) db_save.send() # 需要在代码中写,可以传参数,传入的参数--》db_save_fun 能拿到
# 利用信号能干啥?
1 某个位置记录日志
2 用户只要一注册---》发个注册邮件通知
3 用户只要一异地登录,发个邮件
# 使用信号好处?
解耦
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 # 创建数据库连接时,自动触发
只要用户一注册,我们就发邮件
### views.py from .models import User def index(request): User.objects.create(name='lqz',password='123') return HttpResponse('注册成功') ## __init__.py from django.db.models.signals import post_save def callBack(sender, **kwargs): print(sender) print(kwargs.get('instance').name) print('发短信了') post_save.connect(callBack)
# sqlalchemy 是一个企业级的orm框架 # django 的orm框架---》只能用在django框架中,不能用在别的位置 # sqlalchemy可以单独使用,也可以用在其他框架中 -flask : sqlalchemy -fastapi:sqlalchemy # python界的orm框架 -django orm -sqlalchemy -peewee # 组成 Engine,框架的引擎 Connection Pooling ,数据库连接池 Dialect,选择连接数据库的DB API种类 Schema/Types,架构和类型 SQL Exprression Language,SQL表达式语言 # 安装 pip3 install sqlalchemy # SQLAlchemy本身无法操作数据库,其必须依赖pymsql等第三方插件,Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作,如: MySQL-Python mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname> pymysql mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>] MySQL-Connector mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname> cx_Oracle oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...] 更多:http://docs.sqlalchemy.org/en/latest/dialects/index.html # django中如何反向生成models python manage.py inspectdb > app/models.py
# 操作原生sql ---》用得少 import pymysql import threading # 1 导入 from sqlalchemy import create_engine from sqlalchemy.engine.base import Engine # 2 创建引擎 engine = create_engine( "mysql+pymysql://root:1234@127.0.0.1:3306/cnblogs", max_overflow=0, # 超过连接池大小外最多创建的连接 pool_size=5, # 连接池大小 pool_timeout=30, # 池中没有线程最多等待的时间,否则报错 pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置) ) # 3 使用引擎,拿到链接 # conn = engine.raw_connection() # # 4 剩下的一样了 # cursor=conn.cursor(pymysql.cursors.DictCursor) # cursor.execute('select * from article limit 10') # res=cursor.fetchall() # # print(res) ## 多线程测试: def task(arg): conn = engine.raw_connection() cursor = conn.cursor() cursor.execute( "select * from article" ) result = cursor.fetchall() print(result) cursor.close() conn.close() for i in range(20): t = threading.Thread(target=task, args=(i,)) t.start()
# 1 建个 models.py 里面写 表模型 # 2 把表模型---》同步到数据库中 # 3 增删查改
# 1 导入 import datetime from sqlalchemy import create_engine from sqlalchemy.orm import declarative_base from sqlalchemy import Column, Integer, String, Text, ForeignKey, DateTime, UniqueConstraint, Index Base = declarative_base() # Base 当成 models.Model # 2 创建表模型 class User(Base): __tablename__ = 'users' # 表名 # 写字段 id = Column(Integer, primary_key=True, autoincrement=True) # id 主键 name = Column(String(32), index=True, nullable=False) # name列,索引,不可为空 email = Column(String(32), unique=True) # datetime.datetime.now不能加括号,加了括号,以后永远是当前时间 ctime = Column(DateTime, default=datetime.datetime.now) extra = Column(Text) # 3 没有命令---》后期使用第三方模块,可以有命令 # 目前需要手动做 # sqlalchemy 不能创建数据库,能创建表,删除表,不能删除增加字段(第三方模块) # 3.1 创建引擎 engine = create_engine( "mysql+pymysql://root:1234@127.0.0.1:3306/sqlalchemy01", max_overflow=0, # 超过连接池大小外最多创建的连接 pool_size=5, # 连接池大小 pool_timeout=30, # 池中没有线程最多等待的时间,否则报错 pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置) ) ## 3.2 把表模型同步到数据库中 Base.metadata.create_all(engine) # 3.3 删除表 # Base.metadata.drop_all(engine)
from models import User from sqlalchemy import create_engine # 1 创建引擎 engine = create_engine( "mysql+pymysql://root:1234@127.0.0.1:3306/sqlalchemy01", max_overflow=0, # 超过连接池大小外最多创建的连接 pool_size=5, # 连接池大小 pool_timeout=30, # 池中没有线程最多等待的时间,否则报错 pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置) ) # 2 orm操作--》借助于 engine 得到session(conn)对象 from sqlalchemy.orm import sessionmaker Connection = sessionmaker(bind=engine) conn = Connection() # 3 使用conn---》进行orm操作 # 3.1 增加数据 # user = User(name='lqz', email='3@qq.com') # # 插入到数据库 # conn.add(user) # 放个对象 # # 提交 # conn.commit() # # 关闭链接 # conn.close() # 3.2 查询数据 # 查询User表中id为1的所有记录--》放到列表中 # res=conn.query(User).filter_by(id=1).all() # print(res) ## 3.3 删除 # res = conn.query(User).filter_by(name='lqz').delete() # print(res) # conn.commit() ## 3.4 修改 # res=conn.query(User).filter_by(name='9999').update({'extra':'xxsss'}) # conn.commit()
浙公网安备 33010602011771号