flask知识点

2018-04-20  本文已影响0人  胖虎很可爱

flask:

新建项目使用:

from flask import Flask

app = Flask(__name__)

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

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

初始化参数

配置参数

读取配置参数

app.run的参数

请求方式限定

使用 methods 参数指定可接受的请求方式,可以是多种

@app.route('/',methods=['GET', 'POST'])
def hello():
    return 'hello world'

路由查找方式

同一路由指向两个不同的函数,在匹配过程中,至上而下依次匹配(查找到就不在匹配)

@app.route('/')
def hello():
    return 'hello world'

@app.route('/')
def hello_flask():
    return 'hello flask'

所以上面路由 / 输出的结果为 hello 函数的结果

给路由传参示例

- 大致原理是将参数强转为int, 如果成功, 则可以进行路由匹配
- 如果参数无法转换成功, 就无法匹配该路由

@app.route('/orders/<int:order_id>')
def hello_world(order_id):
    print type(order_id) # 类型为int
    return 'hello world %d' % order_id

重定向redirect示例

方式一: 使用redirect

from flask import redirect
@app.route('/redirect')
def redirect_demo():
    return redirect('http://www.baidu.com')

方式二:使用redirect和url_for

from flask import url_for
@app.route('/redirect')
def redirect_demo():
    # url_for: 根据传入的视图函数名, 找到对应的路由地址
    # 两者通常结合使用
    print url_for('index')
    return redirect(url_for('index'))

返回JSON

方式一: 使用json.dumps()

- 仅仅是将字典转换为JSON格式的字符串. 
- 返回的响应头Content-Type为text/html

from flask import Flask,json
@app.route('/json')
def do_json():
    hello = {"name":"stranger", "say":"hello"}
    return json.dumps(hello)

    # 如果要实现和方式二一样的效果, 可以使用如下方式
    # return 第一个参数: 返回的数据, 第二个参数: 状态码, 第三个参数: 设置响应头信息
    # return json.dumps(json_info), 200, {'Content-Type': 'application/json'}

方式二: 使用jsonify()

- 除了将字典转换为JSON格式的字符串
- 同时会设置响应头Content-Type为application/json
- 建议使用jsonify, 前后端分离的项目中, 前后端都通过JSON进行数据交流

from flask import Flask,json
@app.route('/json')
def do_json():
    hello = {"name":"stranger", "say":"hello"}
    return jsonify(hello)

返回状态码示例

在 Python 中返回状态码有两种方式实现:

- 直接return 
    - 可以自定义返回状态码,可以实现不符合http协议的状态码,例如:error=666,errmsg='查询数据库异常',其作用是为了实现前后端数据交互的方便
- abort方法
    - 只会抛出符合http协议的异常状态码,用于手动抛出异常
    - 具体讲解详见<异常捕获>一节

@app.route('/')
def hello_world():
    return 'hello world',666

正则路由示例

在web开发中,可能会出现限制用户访问规则的场景,那么这个时候就需要用到正则匹配,限制访问,优化访问. 这一点Flask没有Django方便, 在实际开发中, 通常都需要自己定义一个正则路由转换器

from werkzeug.routing import BaseConverter

class Regex_url(BaseConverter):
    def __init__(self,url_map,*args):
        super(Regex_url,self).__init__(url_map)
        self.regex = args[0]

app.url_map.converters['re'] = Regex_url

@app.route('/user/<re("[a-z]{3}"):id>')
def hello_world(id):
    return 'hello %s' %id

自带几种转换器

系统实际提供了6个转换器可供开发者使用. 当使用<>来接收参数时, 就会调用系统默认的转换器进行匹配工作.

- 默认的就是UnicodeConverter, 所以不填转换器名称, 或者使用default、string都是一样的. 
- 默认将参数当做普通字符串对待.

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

获取请求中的数据

flask中代表当前请求的是request对象:

常用的属性如下:

属性 说明 类型
method 记录请求使用的HTTP方法 GET/POST
headers 记录请求中的报文头 EnvironHeaders
url 记录请求的URL地址 string
cookies 记录请求中的cookie信息 Dict
args 记录请求中的查询参数 MultiDict
form 记录请求中的表单数据 MultiDict
data 记录请求的数据,并转换为字符串 *
files 记录请求上传的文件 *

abort 方法

抛出一个给定状态代码的 HTTPException,例如想要用一个页面未找到异常来终止请求,你可以调用 abort(404)。

参数: code – HTTP的错误状态码

abort(404)

只能抛出HTTP协议的状态码

errorhandler 装饰器

注册一个错误处理程序,当程序抛出指定错误状态码的时候,就会调用该装饰器所装饰的方法

参数:code_or_exception – HTTP的错误状态码或指定异常

@app.errorhandler(404)
def internal_server_error(e):
    return '网页找不到了', 404

请求钩子

在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如:在请求开始时,建立数据库连接;在请求结束时,指定数据的交互格式。为了让每个视图函数避免编写重复功能的代码,Flask提供了通用设施的功能,即请求钩子。

请求钩子是通过装饰器的形式实现,类似于Django的中间件. Flask支持如下四种请求钩子:

@app.route('/')
def hello_world():
    print '这里正在执行处理逻辑'
    return 'Hello World!'


# 在处理第一个请求前运行. 应用场景: 比如连接数据库操作
@app.before_first_request
def before_first_request():
    print 'before_first_request'

# 在每次请求前运行。应用场景: 比如对数据做效验. 如果数据有问题, 可以直接返回. 就不会再去执行对应的视图函数
@app.before_request
def before_request():
    print 'before_request'
    # return 'hehe'

# 如果没有未处理的异常抛出, 在每次请求后运行。应用场景: 比如拼接响应头信息. 让所有json.dumps()的数据, 统一增加Content-Type为application/json
@app.after_request
def after_request(response):
    print 'after_request'
    response.headers['Content-Type'] = 'application/json'
    return response


# 在每次请求最后运行,即使有未处理的异常抛出。 可以捕获到异常信息
@app.teardown_request
def teardown_request(e):
    print 'teardown_request %s' % e

状态保持

设置cookie

from flask imoprt Flask,make_response
@app.route('/cookie')
def set_cookie():
    resp = make_response('this is to set cookie')
    resp.set_cookie('username', 'hello')
    return resp

获取cookie

from flask import Flask,request
#获取cookie
@app.route('/request')
def resp_cookie():
    resp = request.cookies.get('username')
    return resp

session数据的设置与获取

session:请求上下文对象,用于处理http请求中的一些数据内容

记得设置secret_key: app.secret_key = 'changhao' secret_key的作用:https://segmentfault.com/q/1010000007295395

from flask import Flask, session, redirect, url_for
@app.route('/set_session')
def set_session():
    session['username'] = 'hello'
    return redirect(url_for('get_session'))

@app.route('/get_session')
def get_session():
    return session.get('username')

Flask的session存放位置

flask和之前用过的其他框架有一点不同的是,它的session默认是完全保留在客户端浏览器中的,也就是说往flask的session中写入数据,最终这些数据将会以json字符串的形式,经过base64编码写入到用户浏览器的cookie里,也就是说无须依赖第三方数据库保存session数据,也无需依赖文件来保存

注意:在实际的开发过程中还是需要把session存放在redis中,通过flask-session扩展实现。

命令行启动服务器

通过使用Flask-Script扩展,我们可以在Flask服务器启动的时候,通过命令行的方式启动。

from flask import Flask
from flask_script import Manager

app = Flask(__name__)
# 把 Manager 类和应用程序实例进行关联
manager = Manager(app)

@app.route('/')
def index():
return '床前明月光'

if __name__ == "__main__":
manager.run()

script的命令行参数

传入参数而不仅仅通过app.run()方法中传参,比如我们可以通过:

python hello.py runserver -host ip地址

数据库:

安装 flask-sqlalchemy
pip install flask-sqlalchemy

如果连接的是mysql数据库,需要安装mysqldb

pip install flask-mysqldb

使用Flask-SQLAlchemy管理数据库

在Flask-SQLAlchemy中,数据库使用URL指定,而且程序使用的数据库必须保存到Flask配置对象的SQLALCHEMY_DATABASE_URI键中。

Flask的数据库设置:

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1:3306/test'

其他设置:

# 动态追踪修改设置,如未设置只会提示警告, 不建议开启
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 查询时会显示原始SQL语句
app.config['SQLALCHEMY_ECHO'] = True

flask-数据库的基本使用:

db.session.add(role)    添加到数据库的session中
db.session.add_all([user1, user2]) 添加多个信息到session中
db.session.commit()     提交数据库的修改(包括增/删/改)
db.session.rollback()   数据库的回滚操作
db.session.delete(user) 删除数据库(需跟上commit)

数据库迁移:

#coding=utf-8
from flask import Flask

from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate,MigrateCommand
from flask_script import Shell,Manager

app = Flask(__name__)
manager = Manager(app)

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1:3306/Flask_test'
db = SQLAlchemy(app)

#第一个参数是Flask的实例,第二个参数是Sqlalchemy数据库实例
migrate = Migrate(app,db) 

#manager是Flask-Script的实例,这条语句在flask-Script中添加一个db命令
manager.add_command('db',MigrateCommand)

if __name__ == '__main__':
    manager.run()
创建迁移仓库
#这个命令会创建migrations文件夹,所有迁移文件都放在里面。
python database.py db init
创建迁移脚本
python database.py db migrate -m 'initial migration'
更新数据库
python database.py db upgrade
返回以前的版本

可以根据history命令找到版本号,然后传给downgrade命令:

python app.py db history

输出格式:<base> ->  版本号 (head), initial migration
python app.py db downgrade 版本号
实际操作顺序:

restful

一、域名:

将api部署在专用域名下:

http://api.example.com

或者将api放在主域名下:

http://www.example.com/api/
二、版本:

将API的版本号放在url中。

http://www.example.com/app/1.0/info
http://www.example.com/app/1.2/info
三、路径:

路径表示API的具体网址。每个网址代表一种资源。 资源作为网址,网址中不能有动词只能有名词,一般名词要与数据库的表名对应。而且名词要使用复数。

示例:

#获取单个商品
http://www.example.com/app/goods/1

#获取所有商品
http://www.example.com/app/goods
四、使用标准的HTTP方法:

对于资源的具体操作类型,由HTTP动词表示。 常用的HTTP动词有四个。

GET     SELECT :从服务器获取资源。
POST    CREATE :在服务器新建资源。
PUT     UPDATE :在服务器更新资源。
DELETE  DELETE :从服务器删除资源。
五、服务器返回的数据格式,应该尽量使用JSON,避免使用XML。
上一篇下一篇

猜你喜欢

热点阅读