创建一个虚拟环境:virtualenv venv
(只有一个变量,那就是虚拟环境的名字)
激活:source venv/bin/activate
退出虚拟环境: deactivate
virtualenvwrapper是virtualenv的拓展功能,可以管理多个虚拟环境
flask主要依赖三个库:
WSGI是什么:
WSGI 是服务器程序与应用程序的一个约定,它规定了双方各自需要实现什么接口,提供什么功能,以便二者能够配合使用。
pip install flask
flask前面都有 app = Flask(__name__)
使用route()装饰器告诉flask什么样的URL需要使用什么样的函数方法
启动应用的方式:
可以直接使用flask命令行:flask run
也可以使用python -m来切换到flask: python -m flask run
在此之前,一定要设置一个环境变量指定flask应用是什么: export FLASK_APP=hello.py
还可以打开调试模式,这样如果改变了代码,server会自动重载:export FLASK_ENV=development
进入Python shell:
python -i filename.py
如果想让这个flask server对于其他计算机可见: flask run --host=0.0.0.0
pip install flask-bootstrap
from flask.ext.bootstrap import Bootstarp
...
bootstrap = Bootstrap(app)
hello world:
# coding=utf-8 #声明源文件编码的语法
from flask import Flask #引入,flask类实现了一个WSGI应用
app = Flask(__name__) #app是flask的实例,通过传入的这个名字确定程序的根目录
@app.route('/') #处理URL和视图函数的关系的程序就是路由
def hello_world():
return 'Hello World!'
if __name__ == '__main__': #这个判断保证当其他文件引用这个文件的时候(from hello import app)不会执行里面的代码,所以引用的时候不会调用app.run()这个函数
app.run(host='0.0.0.0', port=9000) #这里我们对虚拟机做的端口转发端口是9000,0.0.0.0表示监听所有地址,这样就可以本机访问
配置管理:
app.config[]使用的是内置字典数据结构: app.config['DEBUG'] = True
也可以通过配置文件加载:
import settings
app.config.from_object(settings)
调试模式:
代码修改后自动载入:app.run(debug=True)
调试模式会有巨大的安全隐患,所以不能用于生产环境中
!!!路由:
路由设置主页:@app.route('/')
带有变量的路由:@app.route('/user/
或者使用converter来设定变量的类型:
HTTP方法:默认情况只回应GET请求 @app.route('/login', method=['GET', 'POST'])
构造URL:
@app.route('/item/1/')
def item(id):
pass
#构建URL而不是直接在代码中拼URL是为了更改的时候只需要一次性修改URL,不需要到处去替换
with app.test_request_context(): #这个帮助我们在交互模式下产生请求上下文
print url_for('item', id='1') #第一个参数函数名,后面是对应URL规则的变量部分的命名参数
#这个生成的URL是: /item/1/?id=1
print url_for('item', id=2, next='/')
#这个生成的URL是: /item/1/?id=2&next=%2F
HTTP的使用场景:
GET:获取资源
HEAD:想要获取信息,但是只关心消息头部,应用像处理GET请求一样处理它,但是不返回实际的内容。
POST:创建一个新的资源
PUT:完成的替换资源或者创建资源
DELETE:删除资源
OPTIONS:获取资源支持的所有HTTP方法
PATCH:修改某个已有的资源
自定义错误页面:
@app.errorhandler(500)
def internal_server_error(e):
return render_template('500.html'), 500
...
定制静态文件和模板文件的真实目录:
app = Flask(__name__, static_folder='/tmp')
app = Flask(__name__, template_folder='../../templates')
即插视图
这是基于类而不是基于函数的通用视图方式,这样的视图可以支持继承
标准视图需要继承flask.views.View,必须实现dispatch_request
基于调度方法的视图:flask.views.MethodView对每个HTTP方法执行不同的函数
!!!蓝图:
蓝图实现了应用的模块化,使用蓝图让应用层次更清晰。蓝图一般作用于相同的URL前缀,比如/user/id=1,/user/id=2这样的地址,都以/user开头,那么他们就是相同的功能模块,所以放在同一个模块当中
from flask import Blueprint
bp = Blueprint('user', __name__, url_prefix='/user') #表示这个功能模块都是以/user开头的
@bp.route('/')
def index():
return 'User"s Index page'
这里每个模块都会暴露一个bp,然后在主程序中,需要注册这个模块,如果不想使用这个模块,只用去掉对应的注册语句即可:
from flask import Flask
import user
app = Flask(__name__)
app.register_blueprint(user.bp)
这里也可以借助子域名(subdomain)来实现相同的功能
命令行接口:
flask0.11之后,flask中集成了click,可以直接在命令行执行命令启动flask应用
export FLASK_APP=hello.py
export FLASK_DEBUG=1
flask run -h 0.0.0.0 -p 9000
render_tamplate()
最知名的模板系统是jinja2和Mako
使用jinja2模板引擎,支持前后端分离:
渲染部分: render_template('index.html', name = name)
文件名,后面的所有参数都是键值对
模板例子:
{# This is a Comment #} {#...#}模板注释
{{ title | trim }}
#trim是一个过滤器,使用 | 隔开
{{ content }}
模板继承:
基础的骨架模板中:
{%block XXX%}…{%endblock%} 是一个代码块,可以在子模板中进行重载
再看子模板:
{% extends "base.html" %} #表示继承了base.html中的内容
{% block title %}Index{% endblock %}
{% block head %} #表示head代码块被重载
{{ super() }} #这个表示先使用继承的模板中head块的内容,然后基于这个添加css样式
{% endblock %}
{% block content %}
Index
Welcome on my awesome homepage.
{% endblock %}
模板中的宏:
宏类似于函数,可以把常用行为封装为一个可以随时调用的函数:
{% macro hello(name) %}
Hello {{ name }}
{% endmacro %}
模板中为变量赋值:
使用set标签: ` {% set a = 1%}
include语句用于包含一个模块:
渲染时会在include语句的对应位置添加被包含的模块内容:
{% include 'header.html' ignore missing %}
这个ignore missing表示如果这个模板不存在那么就忽略这条语句
import用于在模板中导入宏:
引用调用宏的方法:
#这里有两种方式导入宏
{% import 'macro.html' as macro %} #把整个模板导入到一个变量当中22
{% from 'macro.html' import hello as _hello, strftime %} #从文件中导入特定的宏
{{ macro.hello('world') }}
{{ strftime(time) }}
这里我们暂时不学习Mako模板:
Jinja2尽可能把逻辑从模板中删除,也不支持全部的Python内置函数
但是Mako最后会编译成Python代码以达到性能最优,所以在模板里面可以自由写后端逻辑
每一段程序里面都有很多外部变量,只有像Add这样简单的函数是没有外部变量的,所以一旦你的程序有了外部变量,那么这段程序就不完整,不能独立运行。为了运行程序,就需要将所有的外部变量一个个导入进去,这些值的集合就是上下文。
所以上下文是一个程序需要的外部对象,类似于一个全局变量
对象 | context对象 | 说明 |
---|---|---|
current_app | AppContext | 当前的应用对象 |
g | AppContext | 处理请求时用作临时存储的对象 |
request | RequestContext | 请求对象,封装了Http请求的内容 |
session | RequestContext | 用于存储请求之间需要记住的值 |