蓝图:用于实现单个应用的视图、模板、静态文件的集合。蓝图就是模块化处理的类
简单来说,蓝图就是一个存储操作路由映射方法的容器,主要用来实现客户端请求和URL相互关联的功能。 在Flask中,使用蓝图可以帮助我们实现模块化应用的功能
1> 创建蓝图对象:
from flask import Blueprint
# Blueprint必须指定两个参数,app_orders表示蓝图的名称,__name__表示蓝图所在模块
app_orders = Blueprint('app_orders', __name__)
2> 使用蓝图注册路由:
@app_orders.route('/get_orders')
def get_orders():
return 'get orders page'
3> 在程序实例中注册蓝图:
# app.register_blueprint(app_orders)
# url_prefix的作用是给该蓝图下注册的url添加一个统一的前缀
app.register_blueprint(app_orders, url_prefix='/orders')
目录结构如图:
1> 在main.py
文件中创建app
对象和注册蓝图:
from flask import Flask
from cart import app_cart
app = Flask(__name__)
# 注册蓝图
app.register_blueprint(app_cart, url_prefix='/cart')
if __name__ == '__main__':
app.run()
2> 在cart/__init__.py
文件中创建蓝图对象和导入cart/views.py
文件中的视图函数:
from flask import Blueprint
# 创建蓝图对象,template_folder和static_folder指定该蓝图下的模板文件夹和静态文件夹
# 注:如果有一个与cart同级的templates目录,那么将优先从该目录中寻找模板文件
app_cart = Blueprint('app_cart', __name__, template_folder='templates', static_folder='static')
# 在__init__.py文件被执行的时候,把视图加载进来,让蓝图与应用程序知道有视图的存在
from .views import get_cart
3> 在cart/views.py
文件中定义视图函数:
from flask import render_template
from . import app_cart
@app_cart.route('/get_cart')
def get_cart():
return render_template('cart.html')
assert
是Python中的一个关键字,使用方法如下:
def num_div(num1, num2):
# assert,断言,后面是一个表达式,如果表达式返回真,则断言成功,程序能够继续向下执行;
# 如果表达式返回假,则断言失败,抛出AssertionError异常,终止程序的继续执行
assert isinstance(num1, int)
assert isinstance(num2, int)
assert num2 != 0
print(num1/num2)
import unittest # 导入单元测试模块
# 定义一个类,继承自unittest.TestCase
class TestClass(unittest.TestCase):
# 该方法会首先执行,相当于做测试前的准备工作
def setUp(self):
pass
# 该方法会在测试代码执行完后执行,相当于做测试后的扫尾工作
def tearDown(self):
pass
# 测试方法,方法名需要以`test_`开头
def test_app_exists(self):
pass
方法 | 说明 |
---|---|
assertEqual() | 如果两个值相等,则pass |
assertNotEqual() | 如果两个值不相等,则pass |
assertTrue() | 判断bool值为True,则pass |
assertFalse() | 判断bool值为False,则pass |
assertIsNone() | 不存在,则pass |
assertIsNotNone() | 存在,则pass |
assertIn() | 前者在后者里面,则pass |
assertNotIn() | 前者不在后者里面,则pass |
待测试代码:
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/login', methods=['POST'])
def login():
# 接收参数
username = request.form.get('username')
password = request.form.get('password')
# 校验数据
if not all([username, password]):
resp = {'code': 1, 'msg': '数据不完整'}
return jsonify(resp)
if username == 'admin' and password == 'python':
resp = {'code': 0, 'msg': '登录成功'}
return jsonify(resp)
else:
resp = {'code': 2, 'msg': '用户名或密码不正确'}
return jsonify(resp)
if __name__ == '__main__':
app.run(debug=True)
测试代码:
import unittest
from login import app
import json
class LoginTest(unittest.TestCase):
"""构造单元测试案例"""
def setUp(self):
"""在进行测试之前,先被执行"""
# 设置测试模式,测试模式打开时,待测试代码出现异常时会抛出异常信息
# app.config['TESTING'] = True
app.testing = True
# 使用Flask的app对象创建Web请求的客户端
self.client = app.test_client()
def test_empty_username_password(self):
"""测试用户名或密码不完整的情况"""
# 使用客户端模拟发送Web请求,data为携带的数据
response = self.client.post('/login', data={})
# response是对应视图函数返回的响应对象,data属性是响应体中的数据
json_data = response.data
# 将返回的json字符串转换为字典
resp = json.loads(json_data)
# 获取返回值后进行断言测试
self.assertIn('code', resp, '返回数据格式不正确')
self.assertEqual(resp['code'], 1, '返回状态码不正确')
if __name__ == '__main__':
unittest.main() # 启动测试
import unittest
from author_book import Author, app, db
class DatabaseTest(unittest.TestCase):
def setUp(self):
app.testing = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:[email protected]:3306/flask_test'
db.create_all() # 生成相应的表格
def test_add_author(self):
"""测试添加作者到数据库的操作"""
author = Author(name='zhang')
db.session.add(author)
db.session.commit()
res = Author.query.filter_by(name='zhang').first()
self.assertIsNotNone(res, '未查询到数据')
def tearDown(self):
"""在测试结束后执行,通常用来进行扫尾工作"""
db.session.remove() # 断开和数据库之间的连接
db.drop_all() # 清除所有数据
if __name__ == '__main__':
unittest.main()
采用Gunicorn做wsgi容器,来部署flask程序。Gunicorn(绿色独角兽)是一个Python WSGI的HTTP服务器。从Ruby的独角兽(Unicorn )项目移植。该Gunicorn服务器与各种Web框架兼容,实现非常简单,轻量级的资源消耗。Gunicorn直接用命令启动,不需要编写配置文件,相对uWSGI要容易很多
web开发中,部署方式大致类似。简单来说,前端代理使用Nginx主要是为了实现分流、转发、负载均衡,以及分担服务器的压力。Nginx部署简单,内存消耗少,成本低
Nginx既可以做正向代理,也可以做反向代理:
正向代理:请求经过代理服务器从局域网发出,然后到达互联网上的服务器。特点:服务端并不知道真正的客户端是谁
反向代理:请求从互联网发出,先进入代理服务器,再转发给局域网内的服务器。特点:客户端并不知道真正的服务端是谁
区别:正向代理的对象是客户端。反向代理的对象是服务端
安装gunicorn:pip install gunicorn
查看命令行选项:gunicorn -h
运行命令:
gunicorn -w 4 -b 127.0.0.1:5000 -D --access-logfile ./logs/log main:app
# -w:表示运行的进程数(worker)
# -b:表示绑定的ip地址和端口号(bind)
# -D:表示在后台运行
# --access-logfile:表示记录访问的日志文件
# ./logs/log:表示日志的存储位置
# main:表示运行的Flask文件名称
# app:表示Flask程序的实例名
nginx命令:
# 启动
sudo /usr/local/nginx/sbin/nginx
# 查看
ps aux | grep nginx
# 停止
sudo /usr/local/nginx/sbin/nginx -s stop
# 重启
sudo /usr/local/nginx/sbin/nginx -s reload
设置配置文件:
打开/usr/local/nginx/conf/nginx.conf
文件
upstream flask {
# 设置gunicorn服务器
server 10.666.888.999:5000;
server 10.666.888.999:5001;
}
server {
# 监听80端口
listen 80;
# 本机
server_name localhost;
# 默认请求的url
location / {
# 将请求转发到gunicorn服务器
proxy_pass http://flask;
# 设置请求头,将用户的头信息传递给服务器端
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}