安装:pip install flask
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return
'' #返回字符串,相当于HTTPResponse
render_template('index.html')默认存放路径templates #返回模版,依赖MarkupSafe
redirect('/login') #响应头中加入:location:http://www.baidu.com 重定向302
app.run("0.0.0.0",8888) #监听地址,监听端口
Flask的特殊Response
send_file(文件名称或文件路经+文件名称)#打开并返回文件内容,自动识别文件类型 响应头 Content-Type:文件类型
jsonify({"k1":"v1"}) #返回标准格式的JSON字符串 响应头中Content-Type
#Flask 1.1.1中直接返回dict 本质上是在运行jsonify
from flask import request
request.form 获取formData中的数据 to_dict() 类似字典类型.获取方式:.get() ["key"](有错会报KeyError)
request.args 获取URL中的数据 to_dict() 类似字典类型, .get() ["key"]()(有错会报KeyError)
request.json 请求头中 Content-Type:application/json 存放字典
request.data 请求头中Content-Type 没有Form FormData 存放b""
request.method 请求方式
request.cookies 浏览器的cookie键值对
request.headers 请求头
request.path 路由地址,请求地址
request.url 请求全部地址
request.host 主机位
交由客户端保管的一串加密字符串
在服务器存储的键值对
from flask import session
app.config["SECRET_KEY"] = "!ddsf#$@##()&$@*$@!~~ds"
session["key"] = "value"
@app.route(
rule,#路由地址
endpoint,#Mapping名称对应路由地址 -->通过url_for 反向推推路由地址url_for(endpoint)
methods,#允许进入视图函数的请求方式
defaults,#默认参数
redirect_to,#永久重定向 301 08
strict_slashes,#是否严格遵循路由匹配规则 /
)
app.add_url_rule(rule,
view_func #视图函数
)
动态参数路由:
/get_file/<filename>
def get_file(filename):
...
app = Flask(__name__)
template_folder 模板存放目录
static_folder 静态文件存放目录
static_url_path 静态文件访问路径
class DebugConfig(object):
DEBUG = True
app = Flask(__name__)
app.config.from_object(DebugConfig)
from flask import Blueprint
#当成不能被run的Flask实例
bp = Blueprint("bp",__name__,url_prefix)
#url_prefix 为url前缀
@bp.route("/mybp",endpoint='666')
bp.add_url_rule()
url_for("蓝图标识.endpoint")#url_for("bp.666")
app.register_blueprint()
@app.before_request 在请求进入视图函数之前,做出处理
@app.after_request 在结束视图函数之后,响应客户端之前
@app.errorhandler(HTTP错误码) 重定义错误页面
from flask import views
class Login(views.MethodView):
def get(self,*args,**kwargs):
...
def post(self,*args,**kwargs):
...
app.add_url_rule("/login",endpoint=None,view_func=Login.as_view(name="阿斯达多"))
from flask import views,Flask,render_template,request
from markupsafe import Markup
app = Flask(__name__,template_folder="templates")
class Login(views.MethodView):#继承当前MethodView,让我当前class,可以成为视图类
methods=["GET","POST"]#methods方法要不不写,要不写全。默认写了几个方法,就有几个方法
def get(self,*args,**kwargs):
return render_template("login.html")
def post(self,*args,**kwargs):
userinfo = request.form.to_dict()
user = userinfo.get("user",'')
pwd = userinfo.get("pwd","")
if user == "root" and pwd == "123":
return Markup("<h1>welcome to home</h1>")
return Markup("<h1>密码账号错误</h1>")
app.add_url_rule("/login",endpoint=None,view_func=Login.as_view(name="login"))
#name必须填写否则报错。
if __name__ == '__main__':
app.run()
源码实现:
add_url_rule
自定义类CBV,需要继承MethodView,而MethodView继承View和MethodViewType
as_view()
__init__
自己有dispatch_request,父类也有dispatch_request,先执行自己的dispatch_request
def is_login(func):
def inner(*args,**kwargs):
start_time = time.time()
ret = func(*args,**kwargs)
end_time = time.time()
print(end_time-start_time)
return ret
return inner
class Login(views.MethodView):
decorators = [is_login,]#在类中添加装饰器,其实没什么卵用
def get(self,*args,**kwargs):
...
def post(self,*args,**kwargs):
...
from functools import partial
#demo1:
def add_num(a,b):
return a + b
print(add_num(10,20))#此时打印30
#demo2:
new_func1 = partial(add_num,10)
print(new_func1(5))#15
#demo3:
new_func2 = partial(add_num,5,5)
print(new_func2())#10
#通过上面3个例子,由上面代码知道一些规律了。第一个例子是一个普通函数,第二个例子在函数add_num调用时,我们已经知道了其中一个参数,并且通过这个参数绑定一个新函数,也就是new_func1 = partial(add_num,10),通过调用new_func1,并传入另外一个参数,就可以执行。
#第三个例子与第二个例子相似,只不过新函数new_func2已经将所有参数传入,只要加括号就可以执行函数
import threading
from threading import Thread
import time
from threading import local
#在内存中重新开辟空间,copy原来值。
# rom = {
# 9527:"foo.num = 0",
# 3721:"foo.num = 1",
# 7394:"foo.num = 2",
# ...
# }
class Foo(local):
num = 0
foo = Foo()
def addi(i,):
foo.num = i
time.sleep(0.2)#相当于io操作
print(foo.num,threading.currentThread().ident)#打印数值,打印线程id
for i in range(20):
t = Thread(target=addi,args=(i,))
t.start()
app = Flask(__name__
)
客户端的请求进来时会调用app.__call__
中app.wsgi_app()
返回到request_context
继续返回
__getattr__
方法request = LocalProxy(partial(_lookup_req_object, "request"))
#虽然响应结果是request,但是并没有执行,只是一个新的函数,还没有执行。
__getattr__
方法def __getattr__(self, name):
if name == "__members__":#此时name = "method"
return dir(self._get_current_object())
return getattr(self._get_current_object(), name)#执行_get_current_object
def _get_current_object(self):
if not hasattr(self.__local, "__release_local__"):
#没有"__release_local__"方法,
return self.__local()#返回一个执行方法,此时self.__local 等于newfunc的request对象,执行获得request真身对象
try:
return getattr(self.__local, self.__name__)
except AttributeError:
raise RuntimeError("no object bound to %s" % self.__name__)
????
set key value 用来在数据库中设置一个键值对,哈希存储结构
get key 返回value 用来从数据库取出key的响应value
keys(查询key值) 例如 keys * 查询当前数据中所有的key
keys a* 查询当前数据库中所有 以a开头的key
select dbnum : 总共16个库。数据库切换指定,数据隔离
flask-session是flask的session组件,由于原来flask内置session使用签名cookie保存,该组件将支持session保存到多个地方如:
flask-session下载:
pip install flask-session
flask-session配置:
app.config['SESSION_TYPE'] = 'redis' # session类型为redis
app.config['SESSION_PERMANENT'] = False # 如果设置为True,则关闭浏览器session就失效。
app.config['SESSION_USE_SIGNER'] = False # 是否对发送到浏览器上session的cookie值进行加密
app.config['SESSION_KEY_PREFIX'] = 'session:' # 保存到session中的值的前缀
app.config["SESSION_REDIS"] = Redis(host="127.0.0.1",port=6379,db=0) # 用于连接redis的配置
也可以在settings配置
from redis import Redis
class DebugConfig(object):
DEBUG = True
PERMANENT_COOKIE_NAME = 3600
#浏览器保存的session名字:
SESSION_COOKIE_NAME = "I AM DEBUG SESSION"
SESSION_TYPE = "redis"
SESSION_REDIS = Redis(host="127.0.0.1", port=6379, db=0)
SESSION_KEY_PREFIX = 'my_session'
SESSION_USE_SIGNER = False
SESSION_PERMANENT = False
session存入redis
from flask import Flask,session
from flask_session import Session
from settings import DebugConfig
app = Flask(__name__)
app.config.from_object(DebugConfig)
Session(app)
@app.route("/set_s")
def set_session():
"""创建一个session"""
session["key"] = "i am session"
return "Set Success!"
@app.route("/get_s")
def get_session():
"""获取一个session"""
ses = session.get("key","None")
return ses
if __name__ == '__main__':
app.run()
通过:self._get_interface 改写配置
app的配置才决定第三方组件的对接
ORM中数据表是什么?
Object Relation Mapping 对象关系映射
创建一个Object
class User(object):
pass
下载SQLAlchemy
pip install SQLAlchemy
需要下载pymysql
#my_create_table.py
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column,Integer,String
Base = declarative_base()#实例化官宣模型 Base就是ORM模型
class User(Base):#继承Base,相当于Django Models中Model
__tablename__ = "user"#创建表名为user
"""
id = Column(数据类型,索引,主键,外键,等等)
"""
id = Column(Integer,primary_key=True,autoincrement=True)
name = Column(String(32),index=True)#str相当于sql里的char
#在数据库中创建数据表 或 连接数据库
from sqlalchemy import create_engine
#创建数据库引擎
engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/sqlarm?charset=utf8")
#自动检索所有继承Base的ORM对象,并且创建所有数据表
Base.metadata.create_all(engine)
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Xu Junkai
"""
from my_create_table import User#导入之前做好的ORM表
user1 = User(name="xujunkai")#使用User ORM模型创建一条数据
#写入数据库,首先打开数据库会话,直白就是创建一个操作数据库的窗口
from sqlalchemy.orm import sessionmaker
#导入之前创建好的create_engine
from my_create_table import engine
#创建sessionmaker会话对象,将数据库引擎engine交给sessionmaker
Session = sessionmaker(engine)
#打开会话对象Session
db_session = Session()
#使用db_session会话提交,将db_session中所有指令一次性提交
# db_session.add(user1)
# db_session.commit()
#增加多个数据
user_list = [
User(name = "金城武"),
User(name = "刘德华"),
User(name = "梁朝伟"),
]
db_session.add_all(user_list)
db_session.commit()
from my_create_table import User,engine
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(engine)
db_session = Session()
# 1. select * from user 查询user表中的所有数据
# 语法是这样的 使用 db_session 会话 执行User表 query(User) 取出全部数据 all()
user_all_list = db_session.query(User).all()
print(user_all_list)#[<my_create_table.User object at 0x0000022C81769B00>,...]
for item in user_all_list:
print(item.id,item.name)# ORM对象 直接使用调用属性的方法 拿出对应字段的值
db_session.close()
#查询id>=2的数据
user = db_session.query(User).filter(User.id >=2)
print(user)#SELECT user.id AS user_id, user.name AS user_name #显示原生sql
for item in user:
print(item.id,item.name)
from my_create_table import User,engine
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(engine)
db_session = Session()
# UPDATE user SET name="NBDragon" WHERE id=2 更新一条数据
#将id=2的用户名更改为古天乐
res = db_session.query(User).filter(User.id == 2).update({"name":"古天乐"})
print(res) #1 res就是我们当前这句更新语句所更新的行数
db_session.commit()
db_session.close()
#将id小于等于4的name改为xjk
res = db_session.query(User).filter(User.id <=4).update({"name":"xjk"})
print(res)
#导入 ORM 创建会话
from my_create_table import User,engine
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(engine)
db_session = Session()
#DELETE FROM `user` WHERE id=2;
res = db_session.query(User).filter(User.id==2).delete()
print(res)
db_session.commit()
db_session.close()
#DELETE FROM `user` WHERE id>2;
res = db_session.query(User).filter(User.id>2).delete()
原文:https://www.cnblogs.com/xujunkai/p/12349882.html