Flask1.1总览

Django、Tornado、Flask框架区别

1.Django 主要特点是大而全,集成了很多组件,例如: Models Admin Form 等等, 不管你用得到用不到,反正它全都有,属于全能型框架

2.Tornado 主要特点是原生异步非阻塞,在IO密集型应用和多任务处理上占据绝对性的优势,属于专注型框架

3.Flask 主要特点小而轻,原生组件几乎为0, 三方提供的组件请参考Django 非常全面,属于短小精悍型框架

Django 通常用于大型Web应用由于内置组件足够强大所以使用Django开发可以一气呵成

Tornado 通常用于API后端应用,游戏服务后台,其内部实现的异步非阻塞真是稳得一批

Flask 通常应用于小型应用和快速构建应用,其强大的三方库,足以支撑一个大型的Web应用

Django 优点是大而全,缺点也就暴露出来了,这么多的资源一次性全部加载,肯定会造成一部分的资源浪费

Tornado 优点是异步,缺点是干净,连个Session都不支持

Flask 优点是精悍简单
pip install flask

标准flask模板

from flask import Flask


app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run()

request模块

from flask import request
request.method # 请求方式
request.form # 存放FormData中的数据 to_dict 序列化成字典
request.args # 获取URL中的数据 to_dict 序列化成字典
request.url # 访问的完整路径
request.path # 路由地址
request.host # 主机地址
request.values # 获取 FormData and URL中的数据 不要用to_dict
request.json  # 如果提交时请求头中的Content-Type:application/json 字典操作
request.data  # 如果提交时请求头中的Content-Type 无法被识别 将请求体中的原始数据存放 byte
request.cookies # 获取Cookie中的数据
request.headers # 获取请求头
request.files # 序列化文件存储 save()

使用jinja2模板语法

与Django类似的模板系统

Session的使用

from flask import Flask
from flask import session

app = Flask(__name__)

app.secret_key = 'mysecretkey' 
#secret_key 实际上是用来加密字符串的,如果在实例化的app中没有 secret_key 那么开启session一定会抛异常的



@app.route('/')
def hello_world():
    session['user'] = 'thisisuser'
    return 'Hello World!'

路由系统

@app.route()装饰器参数

from flask import Flask
from flask import url_for


app = Flask(__name__)

'''
methods : 当前 url 地址,允许访问的请求方式
endpoint : 反向url地址,默认为视图函数名 (url_for)
strict_slashes : url地址结尾符"/"的控制 False : 无论结尾 "/" 是否存在均可以访问 , True : 结尾必须不能是 "/"
redirect_to:在路由层面控制跳转页面
'''
@app.route('/',methods=['POST','GET'],endpoint='home',defaults={"id":1},redirect_to='/index')
def hello_world(id):
    print(url_for('home'))
    return 'Hello World!'

if __name__ == '__main__':
    app.run()

app实例化Flask()参数

Flask配置方法:

1.app.config[]配置
app.config['DEBUG'] =True
{
    'DEBUG': False,  # 是否开启Debug模式
    'TESTING': False,  # 是否开启测试模式
    'PROPAGATE_EXCEPTIONS': None,  # 异常传播(是否在控制台打印LOG) 当Debug或者testing开启后,自动为True
    'PRESERVE_CONTEXT_ON_EXCEPTION': None,  # 一两句话说不清楚,一般不用它
    'SECRET_KEY': None,  # 之前遇到过,在启用Session的时候,一定要有它
    'PERMANENT_SESSION_LIFETIME': 31,  # days , Session的生命周期(天)默认31天
    'USE_X_SENDFILE': False,  # 是否弃用 x_sendfile
    'LOGGER_NAME': None,  # 日志记录器的名称
    'LOGGER_HANDLER_POLICY': 'always',
    'SERVER_NAME': None,  # 服务访问域名
    'APPLICATION_ROOT': None,  # 项目的完整路径
    'SESSION_COOKIE_NAME': 'session',  # 在cookies中存放session加密字符串的名字
    'SESSION_COOKIE_DOMAIN': None,  # 在哪个域名下会产生session记录在cookies中
    'SESSION_COOKIE_PATH': None,  # cookies的路径
    'SESSION_COOKIE_HTTPONLY': True,  # 控制 cookie 是否应被设置 httponly 的标志,
    'SESSION_COOKIE_SECURE': False,  # 控制 cookie 是否应被设置安全标志
    'SESSION_REFRESH_EACH_REQUEST': True,  # 这个标志控制永久会话如何刷新
    'MAX_CONTENT_LENGTH': None,  # 如果设置为字节数, Flask 会拒绝内容长度大于此值的请求进入,并返回一个 413 状态码
    'SEND_FILE_MAX_AGE_DEFAULT': 12,  # hours 默认缓存控制的最大期限
    'TRAP_BAD_REQUEST_ERRORS': False,
    # 如果这个值被设置为 True ,Flask不会执行 HTTP 异常的错误处理,而是像对待其它异常一样,
    # 通过异常栈让它冒泡地抛出。这对于需要找出 HTTP 异常源头的可怕调试情形是有用的。
    'TRAP_HTTP_EXCEPTIONS': False,
    # Werkzeug 处理请求中的特定数据的内部数据结构会抛出同样也是“错误的请求”异常的特殊的 key errors 。
    # 同样地,为了保持一致,许多操作可以显式地抛出 BadRequest 异常。
    # 因为在调试中,你希望准确地找出异常的原因,这个设置用于在这些情形下调试。
    # 如果这个值被设置为 True ,你只会得到常规的回溯。
    'EXPLAIN_TEMPLATE_LOADING': False,
    'PREFERRED_URL_SCHEME': 'http',  # 生成URL的时候如果没有可用的 URL 模式话将使用这个值
    'JSON_AS_ASCII': True,
    # 默认情况下 Flask 使用 ascii 编码来序列化对象。如果这个值被设置为 False ,
    # Flask不会将其编码为 ASCII,并且按原样输出,返回它的 unicode 字符串。
    # 比如 jsonfiy 会自动地采用 utf-8 来编码它然后才进行传输。
    'JSON_SORT_KEYS': True,
    #默认情况下 Flask 按照 JSON 对象的键的顺序来序来序列化它。
    # 这样做是为了确保键的顺序不会受到字典的哈希种子的影响,从而返回的值每次都是一致的,不会造成无用的额外 HTTP 缓存。
    # 你可以通过修改这个配置的值来覆盖默认的操作。但这是不被推荐的做法因为这个默认的行为可能会给你在性能的代价上带来改善。
    'JSONIFY_PRETTYPRINT_REGULAR': True,
    'JSONIFY_MIMETYPE': 'application/json',
    'TEMPLATES_AUTO_RELOAD': None,
}
2.使用类方法配置
class Mysetting():
    DEBUG = True
    
app.config.from_object(Mysetting)

app=Flask()参数

app = Flask(__name__,参数)
参数:
static_folder = 'static',  # 静态文件目录的路径 默认当前项目中的static目录
static_host = None,  # 远程静态文件所用的Host地址,默认为空
static_url_path = None,  # 静态文件目录的url路径 默认不写是与static_folder同名,远程静态文件时复用
# host_matching是否开启host主机位匹配,是要与static_host一起使用,如果配置了static_host, 则必须赋值为True
# 这里要说明一下,@app.route("/",host="localhost:5000") 就必须要这样写
# host="localhost:5000" 如果主机头不是 localhost:5000 则无法通过当前的路由
host_matching = False,  # 如果不是特别需要的话,慎用,否则所有的route 都需要host=""的参数
subdomain_matching = False,  # 理论上来说是用来限制SERVER_NAME子域名的,但是目前还没有感觉出来区别在哪里
template_folder = 'templates'  # template模板目录, 默认当前项目中的 templates 目录
instance_path = None,  # 指向另一个Flask实例的路径
instance_relative_config = False  # 是否加载另一个实例的配置
root_path = None  # 主模块所在的目录的绝对路径,默认项目目录

Flask蓝图

使用不同的业务app,类似django中的app
1.项目目录/app01/views/login.py
from flask import Blueprint
login = Blueprint("login",__name__)
@login.route("/login")
def login_func():
    return "登录"
    
2.项目目录/app01/views/register.py
from flask import Blueprint
register = Blueprint("register",__name__)
@register.route("/register")
def register_func():
    return "注册"
    
3.项目目录/app01/__init.py
from flask import Flask
from .views.login import login
from .views.register import register
from app import index
def create_app():
    my_app = Flask(__name__)
    my_app.register_blueprint(index)
    my_app.register_blueprint(login)
    my_app.register_blueprint(register)
    return my_app
    
4.项目目录/manage.py

import app01
if __name__ == '__main__':
    app01.create_app().run()

Flask连接数据库

Flask-Migrate、Flask-Script、Flask-SQLAlchemy

http://www.pythondoc.com/flask-sqlalchemy/quickstart.html

Flask连接数据库的两种操作
        1.DBUtils:用于执行原生SQL的
            用自己的util里面的sqlhelper来完成
        2.SQLAlchemy:遵循他自己的语法来链接
            方式一:SQLAlchemy(app)这种方式有局限性,如果我在其他地方也得用到呢?可以吧它写到全局
            方式二:优点,
                实例化一下:db = SQLAlchemy()
                注册:
                    在settings里面配置一下数据库链接方式
                        SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:root@127.0.0.1/db1?charset=utf8"
                        SQLALCHEMY_POOL_SIZE = 2
                        SQLALCHEMY_POOL_TIMEOUT = 30
                        SQLALCHEMY_POOL_RECYCLE = -1
                    Flask-SQLAlchemy: db.init_app(app)
            
    Flask-Session  #用于吧session保存在其他地方
    Flask-Script  #生成命令
    Flask-Migrate   #数据库迁移
    Flask-SQLAlchemy  #将Flask和SQLAlchemy很好的结合在一起
        #本质、:每次操作数据库就会自动创建一个session连接,完了自动关闭
    Blinker  #信号
    Wtforms  #FORM组件
    用到的组件和版本
        pip3 freeze  #获取环境中所有安装的模块
        pip3 freeze > a.txt
        pip3 freeze > requirements.txt
        #pip3 install pipreqs  #帮你找到当前程序的所有模块,并且自动生成 requirements.txt文件,写入内容
        pipreqs ./  #根目录
             进入程序目录:
                pip install -r requirements.txt #就会把设计到的所有的组件就会装上 
   结构:
   -项目目录
   ---------app
                static
                templates
                views
                __init__.py
                models.py
  -----------manage.py

flask错误处理

蓝图中使用:

1.创建一个py定义错误函数
def page_not_found(err):
    return 'not fucking pages'
2.__init__.py中使用register_error_handler
    def create_app():
        my_app = Flask(__name__)
        my_app.register_blueprint(index)
        my_app.register_blueprint(login)
        my_app.register_blueprint(register)
        my_app.register_error_handler(404,page_not_found)
        return my_app

实例化应用中使用:

from flask import Flask
app = Flask(__name__)
@app.errorhandler(404)
def page_not_found(error_msg):
    return 'waht not page'

@app.errorhandler(500)
def server_error(error_msg):
    return "not server"

##

Flask-Migrate、Flask-Script、Flask-SQLAlchemy