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 能拿到

django 中信号的使用

# 利用信号能干啥?
	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快速使用

# 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

sqlalchemy原生操作

# 操作原生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()

sqlalchemy操作表

# 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()

 

  

  

 

posted @ 2024-03-07 16:20  拆尼斯、帕丁顿  阅读(15)  评论(0)    收藏  举报