Flask后端笔记
HTTP通信与Web框架
流程
- 客户端将请求打包成HTTP的请求报文(HTTP协议格式的请求数据)
- 采用TCP传输发送给服务器端
- 服务器接收到请求报文后按照HTTP协议进行解析
- 服务器根据解析后获知的客户端请求进行逻辑执行
- 服务器将执行后的结果封装成HTTP的响应报文(HTTP协议格式的响应数据)
- 采用刚才的TCP连接将响应报文发送给客户端
- 客户端按照HTTP协议解析响应报文获取结果数据
细节
客户端不一定是浏览器,也可以是PC软件、手机APP、程序
根据服务器端的工作,将其分为两部分:
- 服务器:与客户端进行tcp通信,接收、解析、打包、发送http格式数据
- 业务程序:根据解析后的请求数据执行逻辑处理,形成要返回的数据交给服务器
服务器与Python业务程序的配合使用WSGI协议
Web框架
能够被服务器调用起来,根据客户端的不同请求执行不同的逻辑处理形成要返回的数据的 程序
核心:实现路由和视图(业务逻辑处理)
框架的轻重
重量级的框架:为方便业务程序的开发,提供了丰富的工具、组件,如Django
轻量级的框架:只提供Web框架的核心功能,自由、灵活、高度定制,如Flask、Tornado
明确Web开发的任务
视图开发:根据客户端请求实现业务逻辑(视图)编写
模板、数据库等其他的都是为了帮助视图开发,不是必备的
认识Flask
简介
Flask诞生于2010年,是Armin ronacher(人名)用Python语言基于Werkzeug工具箱编写的轻量级Web开发框架。它主要面向需求简单的小应用。
Flask本身相当于一个内核,其他几乎所有的功能都要用到扩展(邮件扩展Flask-Mail,用户认证Flask-Login),都需要用第三方的扩展来实现。比如可以用Flask-extension加入ORM、窗体验证工具,文件上传、身份验证等。Flask没有默认使用的数据库,你可以选择MySQL,也可以用NoSQL。其 WSGI 工具箱采用 Werkzeug(路由模块) ,模板引擎则使用 Jinja2 。
可以说Flask框架的核心就是Werkzeug和Jinja2。
Python最出名的框架要数Django,此外还有Flask、Tornado等框架。虽然Flask不是最出名的框架,但是Flask应该算是最灵活的框架之一,这也是Flask受到广大开发者喜爱的原因。
与Django对比
django提供了:
django-admin快速创建项目工程目录
manage.py 管理项目工程
orm模型(数据库抽象层)
admin后台管理站点
缓存机制
文件存储系统
用户认证系统
而这些,flask都没有,都需要扩展包来提供
Flask扩展包:
Flask-SQLalchemy:操作数据库;
Flask-migrate:管理迁移数据库;
Flask-Mail:邮件;
Flask-WTF:表单;
Flask-script:插入脚本;
Flask-Login:认证用户状态;
Flask-RESTful:开发REST API的工具;
Flask-Bootstrap:集成前端Twitter Bootstrap框架;
Flask-Moment:本地化日期和时间;
Flask文档
中文文档:http://docs.jinkan.org/docs/flask/
英文文档:http://flask.pocoo.org/docs/0.11/
创建虚拟环境
虚拟环境是一个互相隔离的目录
1. mkvirtualenv flask_py2
2. pip install flask==0.10.1
加sudo 安装不是安在虚拟环境内 是系统里的
pip freeze > requirements.txt # 整合安装包到txt
pip install –r requirements.txt # 安装txt里所有的包
Flask的Hello world程序
# coding:utf-8
# 导入Flask类 不能import * 用哪个导入哪个
from flask import Flask
# 创建flask的应用对象
# __name__表示当前的模块名字
# 模块名,flask以这个模块所在的目录为总目录,默认这个目录中的static为静态目录,templates为模板目录
app = Flask(__name__)
# 装饰器的作用是将路由映射到视图函数index
@app.route('/')
def index():
return 'Hello World'
# Flask应用程序实例的run方法启动WEB服务器
if __name__ == '__main__':
app.run()
运行
python hello.py
查看
浏览器127.0.0.1:5000/
Flask创建app对象
初始化参数
app = Flask(__name__,
static_url_path="/python", # 访问静态资源的url前缀, 默认值是static
static_folder="static", # 静态文件的目录,默认就是static
template_folder="templates", # 模板文件的目录,默认是templates
)
import_name: 导入路径(寻找静态目录和模板目录位置的参数)
static_url_path: 访问静态资源的url前缀, 默认值是static
static_folder: 静态文件的目录 ,默认‘static’
template_folder: 模板文件的目录,默认‘templates’
配置参数
开启debug模式
新建config.cfg内容如下
DEBUG = True
配置参数
app.config.from_pyfile(“config.cfg”) 或
app.config.from_object()
在视图读取配置参数
app.config.get()
current_app.config.get() # 需要导入current_app
app.run的参数
app.run(host=”0.0.0.0”, port=5000)
app.run(host=“0.0.0.0”, port=5000, debug=True)
以上知识点源码
# coding:utf-8
from flask import Flask, current_app
# import demo
# 创建flask的应用对象
# __name__表示当前的模块名字
# 模块名,flask以这个模块所在的目录为总目录,默认这个目录中的static为静态目录,templates为模板目录
app = Flask(__name__,
static_url_path="/python", # 访问静态资源的url前缀, 默认值是static
static_folder="static", # 静态文件的目录,默认就是static
template_folder="templates", # 模板文件的目录,默认是templates
)
# app = Flask("__main__")
# app = Flask("abcdefg")
# 配置参数的使用方式
# 1. 使用配置文件
# app.config.from_pyfile("config.cfg")
# 2. 使用对象配置参数
class Config(object):
DEBUG = True
ITCAST = "python"
app.config.from_object(Config)
# # 3. 直接操作config的字典对象
# app.config["DEBUG"] = True
@app.route("/")
def index():
"""定义的视图函数"""
# a = 1 / 0
# 读取配置参数
# 1. 直接从全局对象app的config字典中取值
# print(app.config.get("ITCAST"))
# 2. 通过current_app获取参数
print(current_app.config.get("ITCAST"))
return "hello flask"
if __name__ == '__main__':
# 启动flask程序
# app.run()
app.run(host="0.0.0.0", port=5000, debug=True)
路由
app.url_map 查看所有路由
默认请求方式为get
浏览器请求为get 调用post_only
添加多种访问方式
同一路由装饰多个视图函数
同名路由优先访问上面的
请求方式不一致为两个独立的逻辑
同一视图多个路由装饰器
使用hi1和hi2都可以访问hi视图
利用methods限制访问方式
@app.route(’/sample’, methods=[‘GET’, ‘POST’])
使用url_for进行反解析
from flask import Flask, current_app, redirect, url_for
@app.route("/index")
def index():
"""定义的视图函数"""
return "hello flask"
@app.route("/login")
def login():
# url = "/"
# 使用url_for的函数,通过视图函数的名字找到视图对应的url路径
url = url_for("index")
return redirect(url)
动态路由
# 路由传递的参数默认当做string处理,这里指定int,尖括号中冒号后面的内容是动态的
# 转换器
# 127.0.0.1:5000/goods/123
# @app.route("/goods/<int:goods_id>")
@app.route("/goods/<goods_id>") # 不加转换器类型, 默认是普通字符串规则(除了/的字符)
def goods_detail(goods_id):
"""定义的视图函数"""
return "goods detail page %s" % goods_id
自定义路由转换器
from werkzeug.routing import BaseConverter
也可以将regex写死但此类只针对一种正则 不如上面的灵活
to_python函数
正则匹配到的参数先调用到to_python函数中进行某些操作过滤等 再传给视图函数
to_url函数
先调用to_url进行处理后再传给send_sms