Flask
- web轻量级框架
- 默认渲染引擎使用jinja2
- route进行url路由
- methods参数设置请求的具体方法
装饰器
- 其实和java里的注解是一个东西
- 将函数调入到装饰器中,嵌套函数,有点像函数模板,减少重复项,方便
初级版
# -*- encoding=UTF-8
def log(func):
def w():
print 'before',func.__name__
func()
print 'before',
return w
@log
def hello():
print 'hello'
if __name__ =='__main__':
hello()
before hello
hello
before
进阶版
#-*- encoding=UTF-8 -*-
def log(func):
def wrapper(*args, **kvargs):
print 'before calling ', func.__name__
print 'args', args, 'kvargs', kvargs
func(*args, **kvargs)
print 'end calling ', func.__name__
return wrapper
@log
def hello(name, age):
print 'hello', name, age
if __name__ == '__main__':
hello(name='hou', age=2)
'''
* 无名字参数
** 有名字参数
'''
before calling hello
args () kvargs {'age': 2, 'name': 'hou'}
hello nowcoder 2
end calling hello
高级版
#-*- encoding=UTF-8 -*-
def log(level, *args, **kvargs):
def inner(func):
'''
* 无名字参数
** 有名字参数
'''
def wrapper(*args, **kvargs):
print level, 'before calling ', func.__name__
print level, 'args', args, 'kvargs', kvargs
func(*args, **kvargs)
print level, 'end calling ', func.__name__
return wrapper
return inner
@log(level='INFO')
def hello(name, age):
print 'hello', name, age
if __name__ == '__main__':
hello(name='hou', age=2)
# name = 'hou' 有名字参数
# ‘hou’ 无名字参数
# 注意,如果装饰器多加一层,如level,就需要装饰器中多包一层函数
INFO before calling hello
INFO args () kvargs {'age': 2, 'name': 'hou'}
hello nowcoder 2
INFO end calling hello
Flask
- nginx进行分发或者负载均衡,到web server上
- server后一层就是后台,进行网站逻辑,架构在框架上
- Flask其实就是在后台架构开发应用
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
- 第1行,引入Flask类,Flask类实现了一个WSGI应用
- 第2行,app是Flask的实例,它接收包或者模块的名字作为参数,但一般都是传递name。让flask.helpers.get_root_path函数通过传入这个名字确定程序的根目录,以便获得静态文件和模板文件的目录。
- 第4~5行,使用app.route装饰器会将URL和执行的视图函数的关系保存到app.url_map属性上。处理URL和视图函数的关系的程序就是路由,这里的视图函数就是hello_world。
- 第8行,主函数,使用这个判断可以保证当其他文件引用这个文件的时候(例如“from hello import app”)不会执行这个判断内的代码,也就是不会执行app.run函数。
第9行,执行app.run就可以启动服务了。默认Flask只监听虚拟机的本地127.0.0.1这个地址,端口为5000。
app.run(debug = True)
上述代码为app的调试模式,只需加上debug=True即可
app.run(debug = True, host = '***', port='***')
- 同样也可指定特定的host和port
注意
- app.route 里尾部加‘/’,页面输入会自动补齐,如@app.route(‘/index/’)
- flash message(session存储)
flash(msg) 发送弹出msg
get_flashed_message 获取msg,显示在html页面上
页面
- Request/Reponse http网页
- HTTP method(get method)
- 静态和模板,用于编辑html页面
- error/重定向
ORM (对象关系映射,数据模型,操作数据库)
- flask-mysqldb安装问题
https://www.cnblogs.com/xinzhiyan/p/8352266.html
- import顺序很关键,一定理清思路
Flask-WTF
Flask-WTF可保护所有表单免受跨站请求伪造的攻击,因此Flask-WTF需要设置一个密匙
app.config['SECRET_KEY'] = '***'
注:web开发中,表单拥有极高的关注度,方便了请求的各种操作
Blueprint
- 结构化的程序管理
- 一个application分割成各自实现不同功能的module,模块化
- app进行注册,也就是说从app中分模块,注册不同的模块,分块操作
遇到问题
调用顺序
import顺序很关键
mysql编码问题
安全期间,建表的时候全部设置成需要的编码格式,utf8
class User(db.Model, UserMixin):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(80), unique=True)
password = db.Column(db.String(32))
salt = db.Column(db.String(32))
#将用户和留言连接
message = db.relationship('Message', backref= 'user', lazy='dynamic')
__table_args__ = {
'mysql_charset': 'utf8'
}
def __init__(self, username, password, salt=''):
self.username = username
self.password = password
self.salt = salt
def __repr__(self):
return ('<User %d %s>' % (self.id, self.username))