Flask——基础知识

Flask应用程序

 一个简单的Flask应用程序

# 导入flask程序
from flask import Flask

# 初始化flask对象
app = Flask(__name__)
# 装饰器模式,新建路由,绑定index视图函数
@app.route("/index")
def index():
    return "index page"

# 判断当前的__name__ 是否是__main__
# __name__ : 如果做为单一模块运行,表示主模块名称:__main__
#            如果做为模块导入,那么就表示当前模块的名字
if __name__ == '__main__':
    # 启动app
    app.run()

运行之后,在浏览器地址栏输入:http://127.0.0.1:5000/index

就可以看到视图函数返回的内容

Flask程序创建的参数

Flask程序创建(app = Flask(初始化参数)的时候其实有很多的参数,前面提到的例子中只写了:__name__。下面会详细说下创建的参数。

源码中的参数是:

这里我只介绍常用的

import_name

# 第⼀一个参数:指定当前应⽤用程序所处于的模块,其可以决定静态⽂文件从哪个位置开始查找, 
# 在加载静态⽂文件时,会从第⼀一个参数指定的模块下开始查找, 
# 如果模块不不存在,会从当前app所在模块的⽬目录下开始找'static'⽂文件夹
# 多数人在这个地方传入__name__。所以默认是__main__,因为不存在__main__模块,所以会从当前模块的同级目录查找static文件夹

static_url_path

静态文件访问路径

static_folder

静态文件所处文件夹

template_folder

 模板文件所处文件夹

默认是:templates

程序运行时的参数

app.run("运行参数")

运行参数:
debug   # 表示启用debug模式
host    # 运行的地址
port    # 绑定的端口
View Code

Flask项目加载配置

从对象中加载配置

from flask import Flask

app = Flask(__name__)

class Config(object):
    #  开启调试模式
    DEBUG = True        # 设置debug开启,当出错会在网页中显示出来。
    NAME = "name"       # 设置一个自定义的变量

# 从对象当中加载
app.config.from_object(Config)

@app.route("/")
def index():
    # a = 1 / 0
    print(app.config.get("NAME"))       # 读取自定义的变量
    return "index page"

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

从路径中加载配置

首先要在当前目录建一个文件,文件名和后缀可以任意取,但是本着见名知意的原则,我取名为了:config.cfg,在文件中我写入了:DEBUG = True

from flask import Flask

app = Flask(__name__)

app.config.from_pyfile("config.cfg")

@app.route("/")
def index():
    # a = 1 / 0
    return "index page"

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

其他方法

app.config['DEBUG'] = True
app.DEBUG = True
app.run(debug = True)
View Code

返回状态码、抛出和捕捉异常

 返回状态码

编码:

@app.route("/")
def index():
    return "状态码", 666

效果

自定义相应头

编码:

@app.route("/")
def index():
    return "状态码", 666, {"name": "zhangshan"}

效果:

抛出异常

编码:

# 导入包
from flask import abort

效果:

捕获异常

编码:

from flask import Flask, abort

app = Flask(__name__)

@app.errorhandler(404)      # 除了404,这些状态码,也可以对指定的错误进行捕获和处理,比如zeroDivisionError
def demo2(e):
    """专⻔门捕获指定的状态码异常信息,然后处理理异常"""
    print(e)
    return '服务器器搬家了了'

@app.route('/index')
def index():
    abort(404)

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

效果:

Flask路由

 请求方法

限定请求方法

 @app.route(‘/‘, methods=[‘GET’, ‘POST’])

获取请求方法

首先要导入request模块,里面封装着用户请求

from flask import request 

然后通过request.method可以获取请求方法。

其他通过request获取的

from flask import Flask
from flask import request

app = Flask(__name__)


@app.route("/index",methods=["GET","POST"])
def index():
    # request : 封装的所有的请求信息
    # request.form : 提取表单数据
    name = request.form.get("name")
    age = request.form.get("age")
    # request.args :提取?后面的数据
    city = request.args.get("city")
    # request.data:提取的是原始数据(json)
    print("request.data = %s" % request.data.decode())
    return "name = %s,age = %s,city = %s" % (name, age, city)


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

默认请求方法

HEAD:获取相应头信息

GET:获取数据,全部信息

OPTIONS:查看某个url可以支持哪些请求方法。

url_map

url_map又可以称为路由视图关系映射,可以通过app.url_map查看。

当同一个路由映射两个视图,当发送请求时,路由会根据map表的顺序从上到下查找,会执行先定义的路由和视图

获取路由的参数

from flask import Flask

app = Flask(__name__)

@app.route('/index/<id>')
def index(id):
    return "id: %s" % id

if __name__ == '__main__':
    app.run(debug=True)
View Code

重定向

首先引入模块:

from flask import redirect

重定向到指定网址

 return redirect(‘http://www.baidu.com’)) 

重定向到指定视图

return redirect(url_for("index"))  # url_for需要导包

重定向传参

return redirect(url_for("order", id=11))
from flask import Flask, redirect, url_for

app = Flask(__name__)


@app.route("/order/<id>")    
def order(id):
    return "id:%s" % id


@app.route('/')
def demo():
    return redirect(url_for("order", id=11))    # 相当于重定向到指定视图对应的url,而且路由中必须有和其匹配的,否则会报错


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

自定义路由匹配转换器

首先导入模块

 from werkzeug.routing import BaseConverter

下面是自带的转换器,Ctrl+鼠标左键点BaseConverter可以看到默认的转换器

DEFAULT_CONVERTERS = {
    'default':          UnicodeConverter,
    'string':           UnicodeConverter,
    'any':              AnyConverter,
    'path':             PathConverter,
    'int':              IntegerConverter,
    'float':            FloatConverter,
    'uuid':             UUIDConverter,
}
View Code

实际中我们需要这个转换器帮我们做更多的筛选。所以需要自定义。

例子:

from flask import Flask
from werkzeug.routing import BaseConverter


class RegexConverter(BaseConverter):
    """⾃自定义转换器器:实现最多传⼊入5个数字"""

    # 重写⽗父类的属性,定义转换器规则
    regex = '[0-9]{5}'

app = Flask(__name__)

# 将自定义的转换器添加到转换器列表中
app.url_map.converters['re'] = RegexConverter


@app.route('/order/<re:order_id>')
def demo1(order_id):
    return 'demo1 %s' % order_id

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

上面例子中写的太死,下面是优化了的:

from flask import Flask
from werkzeug.routing import BaseConverter


class RegexConverter(BaseConverter):
    def __init__(self, url_map, *args):     # 在启动服务器的时候flask就自动的将正则放入了args中了,等浏览器输入会放入url_map中
        super(RegexConverter, self).__init__(url_map)
        self.regex = args[0]

app = Flask(__name__)

# 将自定义的转换器添加到转换器列表中
app.url_map.converters['re'] = RegexConverter


@app.route('/order/<re("[0-9]{5}"):order_id>')
def demo1(order_id):
    return 'demo1 %s' % order_id

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

返回JSON

json模块

json_dict = { 
    ‘name’:’zxc’,    
    ‘age’:18 
}
from flask import Flask, json 
json_str = json.dumps(json_dict) 
View Code

这个成json后,传浏览器的时候Content-Type还是text/html,还需要再修改,不建议

jsonify模块

json_dict = {    
    ‘name’:’zxc’,    
    ‘age’:18 
}
from flask import Flask, jsonify 
json_str = jsonify(json_dict)
View Code

这个转json后,浏览器传输的时候Content-Type变成了application/json。建议使用

请求对象属性

data:读取请求体中的原始字符串,比如json字符串

form:用户通过表单发给服务器的数据,比如POST表单数据到服务器

args:用户通过查询参数发给服务器的数据,也就是url中?后面的参数。比如:http://127.0.0.1/upload?name=lisi中的name=lisi

cookies:用户发送给服务器的cookie数据

headers:请求头信息

method:请求方法

url:请求地址

files:用户发送给服务器的文件信息,比如:文件上传时信息

补充:服务器接收用户上传文件:

pic = request.files.get("pic")
pic.save("./123.jpg")
View Code

请求勾子

 使用装饰器实现监听请求和响应过程

@app.before_first_request

说明:在服务器第一次收到请求前调用,可以做一些初始化,而且只会执行一次,比如连接到数据库

@app.before_request

说明:在请求之前执行

@app.after_request

说明:在请求之后执行

@app.teardown_request

说明:”after_request”和”teardown_request”会在请求处理完成后被调用。区别是”after_request”只会在请求正常退出时才会被调用,它必须传入一个参数来接受响应对象,并返回一个响应对象,一般用来统一修改响应的内容。而”teardown_request”在任何情况下都会被调用,它必须传入一个参数来接受异常对象,一般用来统一释放请求所占有的资源。

以上所以的例子:

from flask import Flask, g, request
 
app = Flask(__name__)
 
@app.before_request
def before_request():
    print 'before request started'
    print request.url
 
@app.before_request
def before_request2():
    print 'before request started 2'
    print request.url
    g.name="SampleApp"
 
@app.after_request
def after_request(response):
    print 'after request finished'
    print request.url
    response.headers['key'] = 'value'
    return response
 
@app.teardown_request
def teardown_request(exception):
    print 'teardown request'
    print request.url
 
@app.route('/')
def index():
    return 'Hello, %s!' % g.name
 
if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)
View Code

访问”http://localhost:5000/”后,会在控制台输出:

before request started
http://localhost:5000/
before request started 2
http://localhost:5000/
after request finished
http://localhost:5000/
teardown request
http://localhost:5000/
View Code

状态保持

cookie

cookie是通过响应将cookie写入到浏览器的

在flask中,先要设置cookie,首先要“做”一个响应

response = make_response('') # make_response这个包需要导入

设置cookie

response.set_cookie('name','zxc') 
response.set_cookie('age', '18', max_age=3600) 

读取cookie

 request.cookies.get('name') 

删除cookie

response.delete_cookie('name')

session

导入模块:

from flask import Flask, session 

加盐:

app.config['SECRET_KEY'] = 'fasf'   # 加盐是让你的原始数据加上这个你随意写入的(一般要用个加密算法得出的结果)的数据再加密,确保数据的安全性

设置session

 session['name'] = 'zxc'

读取session

name = session.get(‘name’)
name = session['name'] 

删除session

 session.pop('name')

设置session过期时间:

# 过期时间, 通过cookie实现的    
from datetime import timedelta    
session.permanent = True # 默认是31天    
app.permanent_session_lifetime = timedelta(minutes=5) # 指定session具体的过期时间
 

注意:无论是cookie还是sesion都是存储在浏览器的一个文件中作为状态保持的,而实际应用中,是将私密信息放到服务器的。用Flask中封装的flask_session中的Session来处理,这个会在你的本地和服务器都存储,看你怎么取。

Flask_Script

Flask中的脚本扩展工具包,再开发中我们可以用pycharm来运行,但是部署到服务器就没有pycharm来启动了,需要这些脚本工具

使用步骤

导入模块

from flask_script import Manager 

创建脚本管理对象

 manager = Manager(app) 

使用脚本管理器对象启动程序

 manager.run() 

再终端上执行脚本命令

python demo.py runserver -p 5001 -d    # -d是开启调试模式

添加脚本

Flask Script扩展提供向Flask插入外部脚本的功能,包括运行一个开发用的服务器,一个定制的Python shell,设置数据库的脚本,cronjobs,及其他运行在web应用之外的命令行任务;使得脚本和系统分开;

Flask Script和Flask本身的工作方式类似,只需定义和添加从命令行中被Manager实例调用的命令;

Manager只有一个参数——Flask实例,也可以是一个函数或其他的返回Flask实例;

编码

@manager.command 
def test_custom_script():    
    print u'这⾥里里实在测试⾃自定义脚本,实现⾃自⼰己的逻辑'
View Code

使用

初始化:(venv)  python manage.py db init 这个命令会在项目下创建 migrations 文件夹,所有迁移脚本都存放其中。
创建第一个版本:(venv) $ python manage.py db migrate -m "initial migration"  检查migrations\versions,会新建一个版本.py,检查里面表格及字段
运行升级 (venv) $ python manage.py db upgrade,会把项目使用的数据库文件,更新为新的表格、字段,同时保留数据

详细的看:http://www.codeweblog.com/flask%E6%89%A9%E5%B1%95flask-script%E6%96%87%E6%A1%A3%E4%B8%AD%E6%96%87%E7%BF%BB%E8%AF%91/

 

posted @ 2018-05-27 21:53  苦行僧95  阅读(356)  评论(0)    收藏  举报