美文网首页
(一) flask入门介绍

(一) flask入门介绍

作者: fanhang64 | 来源:发表于2018-03-20 20:49 被阅读180次

本系列的内容来自读书笔记:《Flask Web 开发 :基于 Python 的 Web 应用开发实战》

一. flask入门

WEB工作原理

  • C/S和B/S架构

  • B/S架构的工作原理

    客户端(浏览器)《=》WEB服务器(Apache,nginx)《=》WSGI《=》Python(flask)

二. Flask框架

(1) 简介

flask是一个非常小的python web框架, 被称为微型框架, 只提供了一个强健的核心, 其他的功能都是通过扩展来实现的, 所以会使用很多的扩展模块

(2) 组成

1. 调试, 路由, wsgi
2. 模板引擎
3. 安装
pip install flask
4. 路由的配置
@app.route('/')  # app可以随意起名字
def index():
    # 视图函数
    pass
5. 完整代码
from flask import Flask  # 导入flask
# 创建flask实例
app = Flask(__name__)
# 配置路由
@app.route('/')
def index():
    return '我是首页'
if __name__ == '__main__':
    app.run()

然后浏览器输入http://127.0.0.1:5000

6. 启动参数run(debug, port, host, threaded)
参数 说明
debug 是否开启调试模式(True/False), 默认为False, 如果开启会自动加载代码
port 指定端口号
host 指定主机名 设置为0.0.0.0
threaded 是否开启多线程, 默认False

实例:

 app.run(debug=True,port=5050,threaded=True,host='0.0.0.0')
7.请求和响应
变量和对象 说明
current_app 当前运行应用的实例
g 处理请求的临时变量, 每次请求都会重置
request 请求对象, 保存客户端的所有HTTP请求的信息
session 会话控制 用于存储会话信息

app对象:

全局应用对象

作用: 公共的全局配置, 可以加在这个对象上

实例:

# 给全局对象添加一个属性
app.good = 'goods'

current_app

在任何的视图中, 可以使用current_app访问到全局的app对象

作用: 因为公共的配置都写在了app对象上, 所以可以在所有的视图函数中, 通过current_app访问全局对象app

from flask import current_app
@app.route('/globalapp/')
def globalapp():
    return '%s 获取全局good属性值, 通过current_app' % current_app.good

request

作用: 获取请求报文中的数据

概述:

  • 浏览器发送到服务器中的所有报文被flask接收后, 创建request对象, request对象被用在视图函数中, 获取请求的数据
  • request对象由flask创建好以后, 引入就可以使用
  • 导入from flask import request

属性:

  1. url : 完整请求url

  2. base_url: 去掉GET参数的url

  3. host_url: 只有主机ip和端口号

  4. path: 路由地址

  5. method: 请求方式

  6. remote_addr: 客户端的ip地址

  7. args: 获取GET请求的参数

    print(request.args['name'])  # 获取参数
    print(request.args.get(['age']))  # 获取参数,获取不到返回None
    
  8. form: 存储表单的数据

  9. files: 用于文件上传

  10. headers: 获取所有的请求头信息

  11. cookies: 获取cookie

获取GET参数:

# http://127.0.0.1:5000/?a=xxx&a=18
print(request.args.get('a',))  # xxx 存在相同的返回第一个
print(request.args.getlist('a',))  # 获取同名的多个参数, 返回列表

三. 路由设置

(1) 无参路由

实例:

@app.route('/test/')
def test():
    return '测试无参路由'

@app.route('/tt/')
@app.route('/tt1/')
@app.route('/tt2/')  # 可以同时添加多个路由
def t():
    return '测试无参路由'

注意: 路由的地址, 可以和视图函数的名称不一致

(2) 有参路由

实例:

@app.route('/welcome/<name>')  # 一个参数的路由
def welcome(name):
    return '欢迎 %s' % name
# 浏览器输入http://127.0.0.1/welcome/张三

# 多个参数的路由
@app.route('/test/<a>/<b>')
def t(a, b):
    print(a, b)
    return '多个参数'

(3) 路由参数的限定

实例:

@app.route('/welcome2/<int:arg>')  # 只能匹配到整形  http://127.0.0.1/welcome/10
@app.route('/welcome2/<float:arg>') # 只能匹配到浮点型  http://127.0.0.1/welcome/10.1
@app.route('/welcome2/<string:arg>')  # 默认, 接受任何不带斜线的字符串
@app.route('/welcome2/<path:arg>')  # 和string相似,但也接受斜线

注意:

  1. 路由末尾的/建议都加上, 因为在路由需要/时浏览器会自动帮你加上, 也就是说输入的时候/可加可不加
  2. 若需要指定参数 将参数名称写在<>中, 视图(函数)的参数和路由的参数<u>名称</u>保持一致
  3. 若要限定参数的类型在<int/float/string/path:参数名称>
  4. 不指定类型默认为string类型, 如果使用path的话/不在是路由的分隔符, 而是代表路径

四. 路由的响应(response)

(1) 响应状态码404(但是请求成功)

实例:

@app.route('/res/')
def res():
    return 'Page not Found ', 404  # 改变返回的状态码值,其实是请求成功的

(2) 通过make_response来构造响应对象

导入: from flask import make_response

实例:

@app.route('/res/')
def res():
    respon = make_response('Page not found')  # 200 单纯的响应结果
    respon = make_response('Page not found', 404)  # 响应结果 改变http状态码
    return respon

五. 重定向(redirect)

作用: 可以在视图直接去跳转

导入: from flask import redirect,url_for

实例:

@app.route('/r_redirect/')
def r_redirect():
    return redirect('/test/', )  # 重定向, 参数为路由名称
    return url_for('t')  # 通过视图函数 反向构造出路由
    print(url_for('t',  a=1, b=2)) # /test/1/2 ,其中参数名a和b与视图函数对应
    return url_for('t', a=1, b=2)  # 通过视图函数 反向构造出路由和参数(关键字为参数名)
    return redirect(url_for('welcome2',arg=101))  # 重定向

六.abort(终止)

  • 如果在视图处理中, 如果出现了异常错误, 可以使用abort函数立即终止视图函数的执行
  • 如果abort函数被触发, 后面的代码和程序就不在执行, 类似python的raise
  • 通过abort函数可以向前端(浏览器端)返回一个HTTP标准中的状态码, 表示出现错误的信息, 如果向浏览器返回一个不存在的Http状态码是没有任何意义的

示例:

@app.route('/')
def index():
    abort(404)  # 抛出404的异常
    print("aa")  # 下面不在执行
    return '我是首页'

错误页面的定制:

@app.errorhandler(404)  # 括号中添加捕获状态码的值, 捕获404错误
def page_not_found(e):  # 必须传一个参数
    print(e)
    return e  # e代表当前状态码对应的信息 正常会调用模板去显示对应状态码的页面

七. 会话控制(cookie和session)

(1) cookie

参数:

Response.set_cookie(
    key,
    value='',
    max_age=None,  # 以秒为单位的cookie寿命
    expires=None,  # 失效时间 datetime对象或者为Unix时间戳
    path='/'  # cookie的有效路径
)

设置cookie实例:

@app.route('/set_cookie/')
def setCookie():  
    response = make_response('设置cookie')
    # Response.set_cookie('name', 'zs')  # 设置cookie
    exp = time.time()+20  # 时间戳
    response.set_cookie('name', 'zs', expires=exp)  # 设置cookie过期时间
    response.set_cookie('name', 'zs', max_age=3600)  # 设置cookie一小时的过期时间
    return Response

获取cookie的实例:

@app.route('/get_cookie/')
def getCookie():
    # 如果没有响应给浏览器会报错, 所有要有默认值
    return request.cookies.get('name', '默认值')  # 获取cookie的实例
    return request.cookies.get('nameaa')  #  如果获取不到会报错
    return request.cookies.get('nameaa') or 'default'  # 获取cookie的实例

删除cookie的实例:

@app.route('/del_cookie/')
def delCookie():
    response = make_response('删除cookie')
    response.delete_cookie('name')
    return Response

(2) session

session基于cookie, session会将唯一标识符session-id存储于cookie中, 每次请求cookie会带着唯一的id去访问, 服务器端会根据唯一的id来区分每一个用户

1. 设置session

Flask对象会将会话储存在客户端的cookie中, 因此需要为应用实例的属性secret_key配置加密种子session, 才可以使用

**导入session **

from flask import session

设置密钥(加密字符串)

app.secret_key = '123456'  # 设置secret_key
app.config['SECRET_KEY'] = '123456'  # 法二, 大写, 推荐使用

设置session:

@app.route('/set_session/')
def setSesstion():
    session['age'] = 18    # 默认存活时间为浏览器会话结束时
    return '设置session'

设置session带过期时间

导入模块:from datetime import timedelta

timedeltadatetime的一个对象, 该对象表示俩个时间的差值

构造函数:

datetime.timedelta(days=0,minutes=0,seconds=0,weeks=0,hours=0)

实例:

@app.route('/set_session/')
def setSesstion():
    from datetime import timedelta
    session.permanent=True # 设置session开启持久化
    app.permanent_session_lifetime = timedelta(minutes=5)  # 设置存活时间为5分钟
    session['age'] = 18
    return '设置session'
2. 获取session
@app.route('/get_session/')
def get_Session():
    return str(session.get('age', 'default'))  # 返回int不能响应,所以强转成str
3. 删除session
@app.route("/del_session/")
def del_session():
    session.pop('age','default')  # 删除key为age的session
    session.clear()  # 删除当前session的所有数据(一个session可能包含name,age等)
    return '删除session'

八. flask-script

概念: 就是一个flask终端运行的解析器 因为项目测试完不需要更改任何的代码, 否则有可能会带风险, 所以要借助这个库通过更改命令完成不同的启动

(2) 安装:pip install flask-script
(3) 使用
from flask-script import Manager
app = Flask(__name__)
manage = Manager(app)  # 实例化Manager
if __name__ == '__main__':
    # app.run(debug=True)
    manage.run()    # 新添加的
(4) 启动参数
-?,--help  # 请求帮助
-h,--HOST  # 设置主机名
-p,--PORT  # 设置端口号
--threaded  # 启用多线程
-d  # 开启调试模式
-r  # 开启自动加载

实例:

python 文件名.py runserver -h 0.0.0.0 -p 5000 -d -r
python 文件名.py runserver -h 0.0.0.0 -p 5000 -d -r  --threaded

九. 蓝本(Blueprint)

概念: 当代码越来越多比较复杂的时候, 可以通过蓝本将对应功能的视图独立出来

步骤:

  1. 新建一个文件user.py

    from flask import Blueprint
    #创建蓝本对象
    user = Blueprint('user',__name__)  # 第一个参数可看做该blueprint对象的姓名,姓名不能与其余的Blueprint对象姓名重复,第二个参数__name__用作初始化
    @user.route('/login/')
    def login():
        return '登录'
    @user.route('/loguut/')
    def logout():
        return '退出登录'
    
  2. 在主文件下添加如下代码

    from user import user
    # app.register_blueprint(user)  # 注册蓝本
    app.register_blueprint(user,url_prefix='/user') # 访问前缀, 访问的时候需要/user/login/
    

拓展:

(1) 蓝本和manage直接的跳转和参数的传递

manage.py文件

app = Flask(__name__)
manage = Manager(app)
@app.route('/')
def index():
    return redirect(url_for('abcd.login'))
    return redirect(url_for('abcd.login',a=1,b=2))  # 带参数的蓝本跳转
from user import user
app.register_blueprint(user)  # 注册蓝本

user.py文件

user = Blueprint("abcd", __name__)  # 第一个参数 根据名字 找视图abcd.login
@user.route('/login/<a>/<b>')  # 带参数的蓝本
def login(a, b):
    print(a, b)  # 1 2   http://127.0.0.1/login/1/2
    return '登录'

注意:

  1. 如果url_for()第二个参数传递的关键字参数(例如:name)名, 在反向构造函数(url_for调用的函数)中不存在则为aa/?name=xx, 如果存在则为aa/name/
(2) 蓝本带前缀路由之间的跳转,manage->user user->manage

manage.py文件

@app.route('/test/')
def test():
    # 如果添加一个login不存在的关键字a, 则地址为http://127.0.0.1/login/zs/?a=xx
    return redirect(url_for('user.login', name='zs'))

app.register_blueprint(user, url_prefix='/user')  # 注册蓝本,带访问前缀

user.py文件中

@user.route('/login/<name>')
def login(name):
    print(name)  # http://127.0.0.1/login/zs
    return '登录'

九. 请求钩子函数

概念: 类似于django的中间件, 写在蓝图中, 只针对蓝图的请求, 在蓝图中需要对应使用钩子函数

钩子函数 功能描述
before_app_first_request 第一次请求之前
before_app_request 每次请求之前
after_app_request 每次请求之后(前提没有异常)
teardown_app_request 每次请求之后

实例:

@user.route('/login/')
def login():
    return '登录'
@user.before_app_first_request
def beforeAppFR():
    print('before_app_first_request')
@user.before_app_request
def beforeApp():
     #可以如下这样使用
    if request.path == '/login/' and request.method="GET": #当请求login视图的时候 如果为 get请求 则请求失败  只是添加一个过滤  确保数据传输和请求更加安全
        abort(404)
    print('before_app_request')
@user.after_app_request
def afterApp(response):
    print(response)
    print('after_app_request')
    return response
@user.teardown_app_request
def teardown(exception):
    print(exception)
    print('teardown_app_request')

相关文章

网友评论

      本文标题:(一) flask入门介绍

      本文链接:https://www.haomeiwen.com/subject/mihiqftx.html