文章目录
Flask总结
1. Flask安装
-
安装virtualenv
-
使用virtualenv来创建虚拟环境,是单独的,被隔离的
virtualenv --no-site-packages venv
-
进入venv中
.\venv\Scripts\activate 进入
deactivate.bat 退出
-
安装flask
pip install flask
验证是否安装成功,直接在该虚拟环境中进入python环境,输入from flask,没有报错即表示安装成功。
2. 路由
2.1 定义
就是一条路径,引导URL从浏览器到WSGI服务器,将处理结果再返回到浏览器上。在 Flask 框架中 ,路由的作用就是为用户请求的URL找出其对应的处理函数 。使用route()其实就是告诉Flask什么样的URL可以触发我们的函数。
2.2 注册路由
Flask 框架中: 根据HTTP请求的URL在路由表中寻找对应的URL规则,找到对应的视图函数,并将视图函数的执行结果返回给WSGI服务器。**注:**Flask封装了一个简单的开发用的WSGI服务器,调用run函数时,该服务器启动。
在Flask里边有一个中转的机制---------endpoint
在Flask内部使用两张表维护路由:
**url_map:**维护URL规则和endpoint的映射。
**view_functions:**维护endpoint和视图函数的映射。
**默认访问点 :**当我们使用route装饰器注册路由时,默认使用被装饰函数的 函数名(name)作为访问点。
**自定义访问点 :**可以在使用route装饰器或调用add_url_rule()方法注册路由时,使用 endpoint关键字参数改变这一默认行为。
两种路由方式
-
调用 add_url_route() 为函数指定一个路由X
def test(): return 'this is test' app.add_url_route('/test',view_func=test)
-
用 route 装饰器将一个url规则绑定到一个视图函数上
@app.route('/test') def test(): return 'this is test'
2.3 动态路由
要给 URL 添加变量部分,你可以把这些特殊的字段标记为 <variable_name> , 这个部分将会作为命名参数传递到你的函数。规则可以用 <converter:variable_name>
指定一个可选的转换器。
@app.route('/user/<username>')
def show_user_profile(username):
# show the user profile for that user
return 'User %s' % username
@app.route('/post/<int:post_id>')
def show_post(post_id):
# show the post with the given id, the id is an integer
return 'Post %d' % post_id
转换器有下面几种:
int 接受整数
float 接受浮点数
path 和默认的相似,但接受斜线
for example:
有这样一个目录结构,假设我们访问其中4个txt文件
/A
|----/B
|----a.txt
|----b.txt
|----/C
|----c.txt
|----d.txt
@app.route('/file/<fname>')
def v_file(fname):
fullname = os.path.join('/A/B',fname)
f = open(fullname)
content = f.read()
f.close()
return cnt
测试结果表明,/file/a.txt和/file/b.txt都没有问题,但是/file/C/c.txt和 /file/C/d.txt却会失败。这是因为,默认情况下,在URL规则中的变量被视为不包含/的字符串。/file/C/c.txt 是没有办法匹配URL规则/file/的。
使用path 的话,四个txt文件都可以访问到
@app.route('/file/<path:fname>')
def v_file(fname):
fullname = os.path.join('/A/B',fname)
f = open(fullname)
content = f.read()
f.close()
return cnt
2.4 添加HTTP方法
HTTP有许多不同的访问 URL 方法。默认情况下,路由只回应 GET 请求,但是通过 route() 装饰器传递 methods 参数可以改变这个行为。例如:
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
do_the_login()
else:
show_the_login_form()
2.5 静态目录路由
当创建应用实例时,Flask将自动添加一条静态目录路由,其访问点 始终被设置为static,URL规则默认被设置为/static,本地路径默认被 设置为应用文件夹下的static子文件夹。
改变默认的本地路径 :可以在创建应用对象时使用关键字参数static_folder改变 默认的静态文件夹。例如,你的静态文件都存放在应用下的assets目录下, 那么可以按如下的方式创建应用对象:
app = Flask(name,static_folder='assets')
2.6 url_for函数
url_for() 函数最简单的用法是以视图函数名(或者app.add_url_route() 定义路由时使用的端点名)作为参数,返回对应的URL。例如,在当前程序中调用url_for(‘index’) 得到的结果是/。调用url_for(‘index’, _external=True) 返回的则是绝对地址,在这个示例中是http://localhost:5000/
print url_for('A',name='B',format='c') #参数分别是 视图函数 、变量、参数
A/B?format=c #输出结果
print url_for('A',_anchor='d') #使用_anchor关键字可以为生成的URL添加锚点
/A#d #结果
#使用 render_template() 方法来渲染模板。Flask 会在 templates 文件夹里寻找模板
@main.route('/', methods=['GET', 'POST'])
def index():
return render_template('main/index.html')
url_for函数有其他功能:
1. 传入url_for() 的关键字参数不仅限于动态路由中的参数。函数能将任何额外参数添加到查询字符串中。例如,url_for(‘index’, page=2) 的返回结果是/?page=2。
2 通过 路由.视图函数 可以定位到其他界面,例如
<a href="{{ url_for('main.index') }}">首页</a>
坑
注意:
-
url_for()函数是用于构建指定函数的URL。url_for()操作的对象是函数,而不是route中的路径。也就是说,需要操作有定义的函数,而不是不存在的函数。
from flask import Flask, url_for app = Flask(\__name__) @app.route('/') def index(): pass @app.route('/login') def LOGIN(): pass with app.test_request_context(): print(url_for('index')) print(url_for('login'))
print(url_for('index'))
没有报错,就是一个反斜杠;print(url_for('login'))
报错,抛出BuildError异常:/ Traceback (most recent call last): File “<\pyshell#12>”, line 3, in print(url_for(‘login’)) File “C:\Python35\lib\site-packages\flask\helpers.py”, line 332, in url_for return appctx.app.handle_url_build_error(error, endpoint, values) File “C:\Python35\lib\site-packages\flask\app.py”, line 1811, in handle_url_build_error reraise(exc_type, exc_value, tb) File “C:\Python35\lib\site-packages\flask_compat.py”, line 33, in reraise raise value File “C:\Python35\lib\site-packages\flask\helpers.py”, line 322, in url_for force_external=external) File “C:\Python35\lib\site-packages\werkzeug\routing.py”, line 1758, in build raise BuildError(endpoint, values, method, self) werkzeug.routing.BuildError: Could not build url for endpoint ‘login’. Did you mean ‘index’ instead?
把login修改为LOGIN:
with app.test_request_context(): print(url_for('index')) print(url_for('LOGIN'))
打印正常:
/ /login
参数:
url_for()
也可以附带一些参数,比如想要完整的URL,可以设置_external
为Ture:
url_for('.static',_external=True,filename='pic/test.png')
返回的url是http://localhost/static/pic/test.png
- endpoint
URL的端点(即函数的名字) - values
URL的变量参数 - _external
如果设置为True
,则生成一个绝对路径URL - _scheme
一个字符串指定所需的URL方案。_external参数必须设置为True,不然会抛出ValueError。 - _anchor
如果设置了这个则给URL添加一个mao - _method
如果设置这个则显示地调用这个HTTP方法
实践
1. 与MySQL建立单次连接
- 利用python实现数据抓取
- 与数据库建立连接并将数据存入数据库
- 利用flask从数据库中取数据显示在web中
注意点:
-
建立连接过程并存入数据
使用creat_engine来创建连接,使用pandas中io来写入数据
def save_data(df, db_name, table_name, user, password): conn = create_engine('mysql+pymysql://root:root@localhost:3306/mysql', encoding='utf-8') pd.io.sql.to_sql(df, 'get_data', conn, if_exists='append', index=False) df.head()
-
从数据库中读取的时候,利用pymysql中的connect进行连接,需要将配置信息写全,并建立一个connection的对象进行操作
connection = pymysql.connect(host='localhost' # host属性 , user='root' # 用户名 , password='root' # 此处填登录数据库的密码 , db='mysql' # 数据库名 , charset='utf8' ) cur = connection.cursor()
因为是单次连接,取完数据之后要断开连接,关闭connection
cur.close() connection.close()
因为没有template、view等渲染,每次运行都会出现下面的错误提示
TypeError: The view function did not return a valid response tuple. The tuple must have the form (body, status, headers), (body, status), or (body, headers).
解决办法是将数据进行转换,用json格式来显示,就没有任何问题了
@app.route('/') def test(): # 从数据库中得到表的数据 sql = 'select * from get_data' cur.execute(sql) data = cur.fetchall() // 查询之后返回全部的元组 return json.dumps(data) // 以json格式来显示