HelloWord程序
创建Python项目
- 打开Pycharm,创建 pure Python类型的项目,创建项目完成之后选择之前创建的py3_flask作为虚拟环境
image.png
第四步路径可以通过在指定的虚拟环境下,输入 which python获得
示例
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_word():
return 'Hello Word'
if __name__ == '__main__':
app.run(debug=True)
第一行:导入Flask类
第三行:Flask函数接收一个参数name,他会指向程序所在的包
第六行:装饰器的作用是将路由映射到试图函数hello_word
第十一、十二行: Flask应用程序实例的run方法,启动WEB服务器
在程序运行过程中,程序实例会使用url_map将装饰器路由和视图的对应关系保存起来
相关参数配置
在上一节实现了一个最简单的 Flask 应用程序,只使用了7行代码,接来对 Flask 程序的创建,运行配置做进一步的了解,具体有:
- Flask 程序初始化参数
- Flask 程序相关配置加载方式
- app.run() 参数
初始化参数
Flask 程序实例在创建的时候,需要默认传入当前 Flask 程序所指定的包(模块),接下来就来详细查看一下 Flask 应用程序在创建的时候一些需要我们关注的参数:
image.png
- import_name
- Flask程序所在的包(模块),传 name 就可以
- 其可以决定 Flask 在访问静态文件时查找的路径
- static_path
- 静态文件访问路径(不推荐使用,使用 static_url_path 代替)
- static_url_path
- 静态文件访问路径,可以不传,默认为:/ + static_folder
- static_folder
- 静态文件存储的文件夹,可以不传,默认为 static
- template_folder
- 模板文件存储的文件夹,可以不传,默认为 templates
程序加载配置
在 Flask 程序运行的时候,可以给 Flask 设置相关配置,比如:配置 Debug 模式,配置数据库连接地址等等,设置 Flask 配置有以下三种方式:
- 从配置对象中加载(常用)
- app.config.from_object()
- 从配置文件中加载
- app.config.from_pyfile()
- 从环境变量中加载(了解)
- app.config.from_envvar()
使用方式
示例:
from flask import Flask
# 1.自定义项目配置类
class Config(object):
'''flask项目的配置信息,以类属性的形式罗列即可'''
DEBUG = True
app = Flask(__name__)
# 方式一:使用类的方式加载项目配置信息
# 2.加载配置类
# app.config.from_object(Config)
# 方式二:使用文件链接方式加载项目配置信息
# app.config.from_pyfile('config.ini')
# 方式三:使用环境变量方式
app.config.from_envvar('FLASKCONFIG')
# 常用的项目配置属性也会在App中保留一份
@app.route('/')
def hello_word():
return 'Hello Word '
if __name__ == '__main__':
app.run()
配置对象
- 从配置对象中加载,创建配置的类,代码如下:
# 配置对象,里面定义需要给 APP 添加的一系列配置
class Config(object):
DEBUG = True
# 创建 Flask 类的对象,指向程序所在的包的名称
app = Flask(__name__)
# 从配置对象中加载配置
app.config.from_object(Config)
运行测试,在修改代码后直接保存,会自动重启服务器
配置文件
-
创建配置文件 config.ini,在配置文件中添加配置
image.png -
使用代码去加载配置
# 创建 Flask 类的对象,指向程序所在的包的名称
app = Flask(__name__)
# 从配置文件中加载配置
app.config.from_pyfile('config.ini')
环境变量(了解)
-
编辑运行的相关配置
image.png
image.png
- 使用代码去加载
# 创建 Flask 类的对象,指向程序所在的包的名称
app = Flask(__name__)
# 加载指定环境变量名称所对应的相关配置
app.config.from_envvar('FLASKCONFIG')
读取配置
- app.config.get()
- 在视图函数中使用 current_app.config.get()
@app.route('/')
def hello_word():
# 获取属性值
print(app.config['DEBUG'])
# 当DEBUG写错时,显示后面的提示信息
print(app.config.get('DEBUG','AA'))
return 'Hello Word '
注:Flask 应用程序将一些常用的配置设置成了应用程序对象的属性,也可以通过属性直接设置/获取某些配置:app.debug = True
路由基本定义
- 明确路由定义的参数,请求方式指定
- PostMan使用
指定路由地址
# 指定访问路径为 demo1
@app.route('/demo1')
def demo1():
return 'demo1'
给路由传参实列
有时我们需要将同一类URL映射到同一个视图函数处理,比如:使用同一个视图函数来显示不同用户的个人信息
# 路由传递参数
@app.route('/user/<user_id>')
def user_info(user_id):
return 'hello %s' % user_id
- 路由传递的参数默认当作string处理,也可以指定参数的类型
# 路由传递参数
@app.route('/user/<int:user_id>')
def user_info(user_id):
return 'hello %d' % user_id
这里指定int,尖括号中的内容是动态的,在此暂时可以理解为接受int类型的值,实际上int代表使用integerConverter去处理url传入的参数
指定请求方式
在Flask中,定义一个路由,默认的请求方式为:
- GET
- OPTIONS(自带)
- HEAD(自带)
如果想添加请求方式,那么可以如下指定
@app.route('/demo2', methods=['GET', 'POST'])
def demo2():
# 直接从请求中取到请求方式并返回
return request.method
完整代示例:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_word():
return 'Hello Word'
# 127.0.0.1/demo1
@app.route('/demo1')
def demo1():
return 'demo1'
# 给路由传参
# 127.0.0.1:5000/user/str数据类型
# <user_id>转换器提取url路径的参数
@app.route('/user/<user_id>')
def demo2(user_id):
return 'user %s' % user_id
# 127.0.0.1:5000/user_int/int数据类型
@app.route('/user_int/<int:user_id>')
def demo3(user_id):
return 'user %d' % user_id
if __name__ == '__main__':
print(app.url_map)
app.run(debug=True)
正则匹配路由
在 web 开发中,可能会出现限制用户访问规则的场景,那么这个时候就需要用到正则匹配,根据自己的规则去限定请求参数再进行访问
具体实现步骤为:
- 导入转换器基类:在Flask中,所有的路由的匹配规则都是使用转换器独享记录
- 自定义转换器:自定义类继承与转换器基类
- 添加转换器到默认的转换器字典中
- 使用自定义转化器实现自定义匹配规则
代码实现
- 导入转换器基类
from werkzeug.routing import BaseConverter
- 自定义转换器
# 自定义正则转换器
class RegexConverter(BaseConverter):
def __init__(self, url_map, *args):
super(RegexConverter, self).__init__(url_map)
# 将接受的第1个参数当作匹配规则进行保存
self.regex = args[0]
- 添加转换器到默认的转换器字典中,并指定转换器使用时名字为: re
app = Flask(__name__)
# 将自定义转换器添加到转换器字典中,并指定转换器使用时名字为: re
app.url_map.converters['re'] = RegexConverter
- 使用转换器去实现自定义匹配规则
- 当前此处定义规则是:3位数字
@app.route('/user/<re("[0-9]{3}"):user_id>')
def user_info(user_id):
return "user_id 为 %s" % user_id
运行测试:http://127.0.0.1:5000/user/123 ,如果访问的url不符合规则,会提示找不到页面
系统自带转换器
DEFAULT_CONVERTERS = {
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
}
系统自带的转换器具体使用方式在每种转换器的注释代码中有写,请留意每种转换器初始化的参数。
完整代码示例
from flask import Flask
# 导入转换器基类
from werkzeug.routing import BaseConverter
app = Flask(__name__)
# 1.自定义转换器类
class RegexConverter(BaseConverter):
# 重写regex属性,当你将正则表达式传入给他的时候,BaseConVerter类处理
def __init__(self, url_map, re):
# 1.初始化父类的init方法,完成正则定义注册工作
super(RegexConverter, self).__init__(url_map)
# 2.初始化子类的init方法
self.regex = re
# 2.注册正则匹配类
app.url_map.converters['re'] = RegexConverter
@app.route('/')
def hello_word():
return 'Hello Word'
# 127.0.0.1:5000/user/123456
# 3.使用自定义正则转换器
@app.route('/user/<re("[0-9]{6}"):user_id>')
def demo1(user_id):
return 'user %s' % user_id
if __name__ == '__main__':
app.run(debug=True)
获取请求参数
- request:flask中代表当前请求的 request 对象
- 作用:在视图函数中取出本次请求数据
- 导入:from flask import request
常用属性如下:
属性 | 说明 | 类型 |
---|---|---|
data | 记录请求的数据,并转换为字符 | * |
form | 记录请求中的表单数据 | MultiDict |
args | 记录请求中的查询参数 | MultiDict |
cookies | 记录请求中的cookie信息 | Dict |
headers | 记录请求中的报文头 | EnvironHeaders |
method | 记录请求使用的HTTP方法 | GET/POST |
url | 记录请求的URL地址 | string |
files | 记录请求上传的文件 | * |
完整代码
from flask import Flask, request
app = Flask(__name__)
@app.route('/')
def hello_word():
return 'Hello Word'
'''
get: 获取服务器数据,问号后面携带的参数,告知服务器获取的数据
post: 往服务器新增数据,请求体里面携带的参数:一般是需要存到数据库的数据
'''
# 127.0.0.1:5000/get?user_name=curry&age=18
@app.route('/get')
def demo1():
"""提取get请求问号后面携带的参数"""
# request.method 获取访问方式:后面字符串必须大写
if request.method == 'GET':
# 方式: request.method.args.get('key',"")
user_name = request.args.get('user_name', '')
age = request.args.get('age', '')
return '%s %s' % (user_name, age)
else:
return '405请求方式不正确'
@app.route('/post', methods=['post'])
def demo2():
'''提取post请求体中携带的参数'''
if request.method == 'POST':
# 方式
user_name = request.form.get('user_name', '')
user_id = request.form.get('user_id', '')
return '%s %s' % (user_name, user_id)
else:
return '405请求方式不正确'
@app.route('/upload', methods=['post'])
def demo3():
if request.method == 'POST':
# 方式:request.files.get('key', '')
file = request.files.get('pic', '')
file.save('./1.jpg')
return 'upload succes'
else:
return '405请求方式不正确'
if __name__ == '__main__':
app.run(debug=True)
构造响应数据
视图常用逻辑
- 返回JSON
- 重定向
- Url_for
- 自定义状态码
返回JSON
在使用Flask写一个接口时候需要给客户端返回JSON数据,在Flask中可以直接使用jsonify生成一个JSON的响应
# 返回JSON
@app.route('/demo3')
def demo3():
json_dict = {
"user_id": 10,
"user_name": "laowang"
}
return jsonify(json_dict)
不推荐使用json.dumps转成JSON字符串直接返回,因为返回的数据要符合HTTP协议规范,如果是JSON需要指定content-type:application/json
完整代码:
from flask import Flask, jsonify
import json
app = Flask(__name__)
@app.route('/')
def hello_word():
return 'Hello Word'
@app.route('/json')
def demo1():
'''json数据转换'''
dict = {
'name': 'james',
'age': 34,
'info': {
'team': 'laker'
}
}
# 序列化: 将python对象转换成json字符串
json_str = json.dumps(dict)
# 反序列化: 将json字符串转换成python对象
my_json = json.loads(json_str)
# 1.能将python对象转换成json字符串
# 2.能将相应体数封装成响应对象并返回
# 3.指明了响应数据格式: ContentType = 'application/json'
my_jsons = jsonify(dict)
return my_jsons
# return json_str
if __name__ == '__main__':
app.run(debug=True)
重定向
- 重定向到百度
# 重定向
@app.route('/demo4')
def demo4():
return redirect('http://www.baidu.com')
- 重定向到自己写的视图函数
- 可以直接填写自己的Url路径
- 也可以使用url_for生成指定试图函数所对应的url
@app.route('/demo1')
def demo1():
return 'demo1'
# 重定向
@app.route('/demo4')
def demo4():
return redirect(url_for('demo1'))
- 重定向到带有参数的视图函数
- 在url_for函数中传入参数
# 路由传递参数
@app.route('/user/<user_id>')
def user_info(user_id):
return 'hello %d' % user_id
# 重定向
@app.route('/demo4')
def demo4():
# 使用 url_for 生成指定视图函数所对应的 url
return redirect(url_for('user_info', user_id=100))
完整代码:
from flask import Flask, redirect, url_for
app = Flask(__name__)
@app.route('/index')
def hello_word():
return 'Hello Word'
@app.route('/redirect')
def redirects():
'''重定向到百度'''
# 使用redirect方法进行重定向
return redirect('http://www.baidu.com')
@app.route('/demo2')
def demo2():
'''重定向到自身的根路径'''
# url_for : url反向解析函数
# 根据函数名称一一解析出对应的url
return redirect(url_for('hello_word'))
if __name__ == '__main__':
app.run(debug=True)
自定义状态码
- 在Flask中,可以很方便的返回自定义状态码,以实现不符合http协议的状态码,例如: status code:666
@app.route('/demo4')
def demo4():
return '状态码为 666', 666
装饰器路由具体实现梳理
image.png- Flask有两大核心:Werkzeug和Jinja2
- Werkzeug实现路由\调试和web服务器网关接口
- Jinja2实现了模板
- Werkzeug是一个遵循WSGI协议的python函数库
- 其内部实现了很多Web框架底层的东西,比如request和response对象;
- 与WSGI规范的兼容;支持Unicode;
- 支持基本的会话管理和签名Cookie;
- 集成URL请求路由等。
- Werkzeug库的 routing 模块负责实现 URL 解析。不同的 URL 对应不同的视图函数,routing模块会对请求信息的URL进行解析,匹配到URL对应的视图函数,执行该函数以此生成一个响应信息。
routing模块内部有: - Rule类
- 用来构造不同的URL模式的对象,路由URL规则
- Map类
- 存储所有的URL规则和一些配置参数
- BaseConverter的子类
- 负责定义匹配规则
- MapAdapter类
- 负责协调Rule做具体的匹配的工作
状态保持
- 因为http是一种无状态协议,浏览器请求服务器是无状态的。
- 无状态:指一次用户请求时,浏览器\服务器无法知道之前这个用户做过什么,每次请求都是新的请求
- 无状态原因:浏览器与服务器之间是使用socket套接字进行通信,服务器将请求结果返回给浏览器之后,会关闭当前的socket连接,而且服务器也会在处理页面完毕之后销毁页面对象
- 有时需要保持下来用户浏览的状态,比如用户是否登陆过,浏览过哪些商品等
- 实现状态保存主要有两种方式
- 在客户端保存用cookie
- 在服务端保存用session
无状态协议
1.协议对于事务处理没有记忆能力
2.对同一个 url 请求没有上下文关系
3.每次的请求都是独立的,它的执行情况和结果与前面的请求和之后的请求是无直接关系的,它不会受前面的请求应答情况直接影响,也不会直接影响后面的请求应答情况
4.服务器中没有保存客户端的状态,客户端必须每次带上自己的状态去请求服务器
5.人生若只如初见
Cookie
-
Cookie:指某些网站为了辨别用户身份、进行会话跟踪而储存在用户本地的数据(通常经过加密)。
- 复数形式Cookies.
- Cookie是由服务器端生成,发送给客户端浏览器,浏览器会将Cookie的key/value保存,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie)。
- Cookie的key/value可以由服务器端自己定义。
-
提示:
- Cookie是存储在浏览器中的一段纯文本信息,建议不要存储敏感信息如密码,因为电脑上的浏览器可能被其它人使用
-Cookie基于域名安全,不同域名的Cookie是不能互相访问的- 如访问itcast.cn时向浏览器中写了Cookie信息,使用同一浏览器访问baidu.com时,无法访问到itcast.cn写的Cookie信息
- 浏览器的同源策略
- 当浏览器请求某网站时,会将本网站下所有Cookie信息提交给服务器,所以在request中可以读取Cookie信息
- Cookie是存储在浏览器中的一段纯文本信息,建议不要存储敏感信息如密码,因为电脑上的浏览器可能被其它人使用
设置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', 'itcast')
return resp
image.png
设置过期时间
@app.route('/cookie')
def set_cookie():
response = make_response('hello world')
response.set_cookie('username', 'itheima', max_age=3600)
return response
image.png
获取cookie
from flask import Flask,request
#获取cookie
@app.route('/request')
def resp_cookie():
resp = request.cookies.get('username')
return resp
image.png
完整代码:
from flask import Flask, make_response, request
app = Flask(__name__)
@app.route('/')
def hello_word():
return 'Hello Word'
@app.route('/login')
def login():
'''登录成功后借助cookie保存登录信息'''
# 1.创建响应对象
response = make_response('login success')
# 2.借助响应对象的set_cookie方法设置键值对
'''
参数1: key 参数2: value 参数3: max_age = 表示过期时长
'''
response.set_cookie('user_name', 'laowang', max_age=3600)
response.set_cookie('user_id', '1', max_age=3600)
return response
@app.route('/index')
def index():
'''再次请求首页的时候,提起cookie中的用户信息'''
user_name = request.cookies.get('user_name', '')
user_id = request.cookies.get('user_id', '')
return 'index %s -- %s' % (user_name, user_id)
@app.route('/login_out')
def loginout():
'''退出登录删除cookie中用户数据'''
# 1.构建响应对象
respone = make_response('login out delete')
# 2.利用响应对象中的delete_cookie方法删除对应的cookie
respone.delete_cookie('user_name')
respone.delete_cookie('user_id')
return respone
if __name__ == '__main__':
app.run(debug=True)
Session
- 对于敏感、重要的信息,建议要存储在服务器端,不能存储在浏览器中,如用户名、余额、等级、验证码等信息
- 在服务器端进行状态保持的方案就是Session
- Session依赖于Cookie
session数据的获取
session:请求上下文对象,用于处理HTTP请求中的一些数据内容
@app.route('/set_session')
def set_session():
session['username'] = 'itcast'
return 'set_session ok!'
@app.route('/get_session')
def get_session():
return session.get('username')
记得设置secret_key: app.secret_key = 'password' 的作用
https://segmentfault.com/q/1010000007295395
完整代码:
from flask import Flask, session
app = Flask(__name__)
# 加密
app.secret_key = 'asdfghjkl'
@app.route('/')
def hello_word():
return 'Hello Word'
@app.route('/login')
def login():
'''登录成功借助cookie储存用户登录信息到服务器'''
# session 会将用户数据存储到服务器中,一般是数据库
session['user_name'] = 'laosong'
session['user_id'] = '1'
return 'login sucess'
@app.route('/index')
def index():
'''再次请求首页的时候可以借助session提取用户的登录信息'''
user_name = session.get('user_name')
user_id = session.get('user_id')
return 'user_name : %s, user_id : %s' % (user_name, user_id)
@app.route('/out')
def login_out():
'''退出后删除'''
session.pop('user_name', '')
session.pop('user_id', '')
return 'out susser'
if __name__ == '__main__':
app.run(debug=True)
请求钩子
在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如:
- 在请求开始时,建立数据库连接;
- 在请求开始时,根据需求进行权限校验;
- 在请求结束时,指定数据的交互格式;
为了让每个视图函数避免编写重复功能的代码,Flask提供了通用设施的功能,即请求钩子。
请求钩子是通过装饰器的形式实现,Flask支持如下四种请求钩子:
- before_first_request
- 在处理第一个请求前执行
- before_request
- 在每次请求前执行
- 如果在某修饰的函数中返回了一个响应,视图函数将不再被调用
- after_request
- 如果没有抛出错误,在每次请求后执行
- 接受一个参数:视图函数作出的响应
- 在此函数中可以对响应值在返回之前做最后一步修改处理
- 需要将参数中的响应在此参数中进行返回
- teardown_request:
- 在每次请求后执行
- 接受一个参数:错误信息,如果有相关错误抛出
完整代码:
from flask import Flask
from flask import abort
app = Flask(__name__)
# 在第一次请求之前调用,可以在此方法内部做一些初始化操作
@app.before_first_request
def before_first_request():
print("before_first_request")
# 在每一次请求之前调用,这时候已经有请求了,可能在这个方法里面做请求的校验
# 如果请求的校验不成功,可以直接在此方法中进行响应,直接return之后那么就不会执行视图函数
@app.before_request
def before_request():
print("before_request")
# if 请求不符合条件:
# return "laowang"
# 在执行完视图函数之后会调用,并且会把视图函数所生成的响应传入,可以在此方法中对响应做最后一步统一的处理
@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")
@app.route('/')
def index():
return 'index'
if __name__ == '__main__':
app.run(debug=True)
- 在第一次请求时打印
before_first_request
before_request
after_request
teardown_request
- 在第二次请求时打印
before_request
after_request
teardown_request
异常捕获
HTTP异常主动抛出
- abort 方法
- 抛出一个给定状态的HTTPException 或者 指定响应, 例如想要用一个页面未找到异常来终止请求,可以调用abort(404)
- 参数
- code-HTTP的错误状态码(必须)
# abort(404)
abort(500)
抛出状态码的话,只能抛出 HTTP 协议的错误状态码
捕获错误
- errorhandler装饰器
- 注册一个错误处理程序,当程序抛出指定错误状态码的时候,就会调用该装饰器所装饰的方法
- 参数
- code_or_exception-HTTP的错误状态码或指定异常
- 例如统一处理状态码为500的错误给用户友好提示:
@app.errorhandler(500)
def internal_server_error(e):
return '服务器搬家了'
- 捕获指定异常
@app.errorhandler(ZeroDivisionError)
def zero_division_error(e):
return '除数不能为0'
完整代码:
from flask import Flask, redirect, abort
app = Flask(__name__)
@app.route('/')
def hello_word():
# 定义两个错误
# a = 1/0
# abort 指定错误
abort(404)
return 'Hello Word'
@app.errorhandler(404)
def handler(e):
'''404'''
print(e)
# 重定向
return redirect('http://hd.mi.com/webfile/zt/hd/2014042802/cn.html')
@app.errorhandler(ZeroDivisionError)
def error(a):
'''捕获异常'''
return '不能除零'
if __name__ == '__main__':
app.run(debug=True)
上下文
上下文:即语境,语意,在程序中可以理解为在代码执行到某一时刻时,根据之前代码所做的操作以及下文即将要执行的逻辑,可以决定在当前时刻下可以使用到的变量,或者可以完成的事情。
Flask中有两种上下文,请求上下文和应用上下文
Flask中上下文对象:相当于一个容器,保存了 Flask 程序运行过程中的一些信息。
请求上下文(request context)
在 flask 中,可以直接在视图函数中使用 request 这个对象进行获取相关数据,而 request 就是请求上下文的对象,保存了当前本次请求的相关数据,请求上下文对象有:request、session
- request
- 封装了HTTP请求的内容,针对的是http请求。举例:user = request.args.get('user'),获取的是get请求的参数。
- session
- 用来记录请求会话中的信息,针对的是用户信息。举例:session['name'] = user.id,可以记录用户信息。还可以通过session.get('name')获取用户信息。
应用上下文(application context)
它的字面意思是 应用上下文,但它不是一直存在的,它只是request context 中的一个对 app 的代理(人),所谓local proxy。它的作用主要是帮助 request 获取当前的应用,它是伴 request 而生,随 request 而灭的。
应用上下文对象有:current_app,g
current_app
应用程序上下文,用于存储应用程序中的变量,可以通过current_app.name打印当前app的名称,也可以在current_app中存储一些变量,例如:
- 应用的启动脚本是哪个文件,启动时指定了哪些参数
- 加载了哪些配置文件,导入了哪些配置
- 连了哪个数据库
- 有哪些public的工具类、常量
- 应用跑再哪个机器上,IP多少,内存多大
current_app.name
current_app.test_value='value'
g变量
g 作为 flask 程序全局的一个临时变量,充当者中间媒介的作用,我们可以通过它传递一些数据,g 保存的是当前请求的全局变量,不同的请求会有不同的全局变量,通过不同的thread id区别
g.name='abc'
不同的请求,会有不同的全局变量
两者区别:
- 请求上下文:保存了客户端和服务器交互的数据
- 应用上下文:flask 应用程序运行过程中,保存的一些配置信息,比如程序名、数据库连接、应用信息等
上下文中的对象只能在指定上下文中使用,超出范围不能使用 请求上下文和应用上下文原理实现:https://segmentfault.com/a/1190000004223296
完整代码
from flask import Flask, request, session, current_app, g
app = Flask(__name__)
app.secret_key = 'asdfghjkl'
@app.route('/')
def hello_word():
# 请求上下文
print(request.method)
print(request.url)
session['user_name'] = 'curry'
print(session.get('user_name', ''))
# 应用上下文
current_app.config.get("DEBUG")
g.user = 'James'
print(g.user)
return 'Hello Word'
if __name__ == '__main__':
app.run(debug=True)
Flask-script扩展
通过使用Flask-Script扩展,我们可以在Flask服务器启动的时候,通过命令行的方式传入参数。而不仅仅通过app.run()方法中传参,比如我们可以通过:
python hello.py runserver -host ip地址
以上代码告诉服务器在哪个网络接口监听来自客户端的连接。默认情况下,服务器只监听来自服务器所在的计算机发起的连接,即localhost连接。
我们可以通过python hello.py runserver --help来查看参数。
image.png
代码实现
- 安装Flask-Script
pip install flask-script
- 集成Flask-Script
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()
Flask-Script 还可以为当前应用程序添加脚本命令,后续项目中会使用到
网友评论