一、Flask入门和视图
需要安装Pycharm专业版
1. Flask简介
Python后端的2个主流框架
- Flask 轻量级框架
- Django 重型框架
-
Flask是一个基于Python实现的web开发微框架
官方文档:https://flask.palletsprojects.com/
中文文档:https://dormousehole.readthedocs.io/
-
Flask是一个基于MVC设计模式的Web后端框架
- MVC:
- M: Model 数据模型
- V: View 界面
- C: Controller 控制器
- MVT:
- M: Models 模型(数据)
- V: Views 视图(控制器)
- T: Templates 模板(界面)
- MVC:
-
Flask依赖的三个库
- Jinja2:模板引擎 {% %}
- 模板:静态HTML+模板语言{% %}
- Werkzeug WSGI 工具集
- Jinja2:模板引擎 {% %}
-
Flask流行的主要原因
- 1.有非常齐全的官方文档,上手非常方便工
- 2.有非常好的扩展机制和第三方扩展环境,工作中常见的软件都会有对应的扩展。自己动手实现扩展也很容易
- 3.社区活跃度非常高
- 4.微型框架的形式给了开发者更大的选择空间
2. 创建虚拟环境
# 打开CMD
# 安装virtualenv虚拟环境(windows)
pip install virtualenv virtualenvwrapper-win
# 查看虚拟环境
workon
# 切换/进入虚拟环境
workon env-name
# 新建虚拟环境
mkvirtualenv env-name
# 删除虚拟环境
rmmkvirtualenv env-name
3. 使用Flask
第一个Flask项目
-
创建项目
-
选择虚拟环境:
workon flask2env
-
在虚拟环境中安装Flask2:
pip install flask==2.2.3
添加现有解释器,在Windows当前用户下的Envs目录下。如
C:\Users\username\Envs\flask2env\Scripts\python.exe
-
打开Pycharm专业版,创建好Flask项目并配置好虚拟环境flask2env
-
创建helloFlask.py,示例代码如下:
# 导入Flask应用对象 from flask import Flask # 创建Flask应用对象 app = Flask(__name__) # 路由+视图函数hello_world @app.route('/') def hello_world(): # put application's code here # 响应:返回给浏览器的数据 return 'Hello World!' # 添加一个路由和视图函数 @app.route('/index/') def index(): return 'Index 首页' if __name__ == '__main__': # 启动服务器 app.run()
-
启动参数相关,run()启动的时候还可以添加参数:
- debug 是否开启调试模式,开启后修改过python代码会自动重启
- port 启动指定服务器的端口号,默认是5000
- host 主机,默认是127.0.0.1,指定为0.0.0.0代表本机所有ip
-
-
注意:
-
有Anaconda的若是Python版本不一致可以按照如下切换python版本
# 安装一个python 3.9的环境 conda create -n py39 python=3.9 # 激活这个新配置的环境 ,这样就切换了python版本 conda activate py39 # 列出当前安装的所有pyhon环境 conda info -e # 如果切换环境后,又想回到之前的环境,可以通过命令 conda deactivate # 删除一个已有的环境 conda remove --name python34 --all
-
如果遇到报错:
ImportError:cannot import name 'url_quote' from 'werkzeug.urls'
是因为flask2.2.3版本不兼容Werkzeug3.0以上
因此我们可以在虚拟环境中执行
pip install Werkzeug==2.3.7
-
app.run
参数无效问题- 运行
app.run(host="127.0.0.1",port=5002,debug=True)
,但是服务启动后,还是默认的ip和端口http://127.0.0.1:5000
,debug模式也是off - 原因:pycharm识别出你是flask项目
- 解决方案:切换为python的运行模式,重新编辑配置,配置编辑>运行/调试配置>新增Pyhton配置运行当前文件即可。查看更详细说明
- 运行
-
4. 模板渲染
-
模板渲染,使用
render_template('xxx.html',name='张三法外狂徒')
】xxx.html
是在templates目录下的xxx.html文件- 在
xxx.html
文件中使用{{name}}
可以取到传过来的name值
from flask import Flask, render_template, jsonify app = Flask(__name__) app.config['DEBUG'] = True @app.route('/') def home(): # 返回字符串 return 'Flask Home1' # 模板渲染 @app.route('/index/') def index(): # 返回字符串:支持HTML标签 # return '<h1>Flask Index</h1>' # 模板渲染 这是目录templates下的index.html,name可以在index中使用模板语法{{name}}取到 return render_template('index.html', name='法外狂徒张三') # JSON # jsonify:序列化 # return jsonify({'name': '张三', 'age': 33}) if __name__ == '__main__': # 启动服务器 不生效 app.run(debug=True, port=5001, host='127.0.0.2')
-
使用将static的css文件导入到template下的html文件中
-
静态使用,相当于反向解析:
url_for('static', filename='hello.css')
指定
static
目录下的hello.css
- 在对应的
html
文件中使用
<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> {# 3种导入静态文件的方式 #} <!--<link rel="stylesheet" href="../static/index.css"> --> <!--<link rel="stylesheet" href="/static/index.css"> --> {# 这是目录static下的index.css #} <link rel="stylesheet" href="{{ url_for('static',filename='index.css') }}"> </head> <body> <h2>Index</h2> <hr/> <h4>name:{{ name }}</h4> </body> </html>
- 在对应的
-
5. 项目拆分
代码全都写在
app.py
一个文件中是不现实的我们可以对项目进行简单拆分
-
在项目顶级目录,新建目录App(包),App目录里面新建static和templates目录,新建文件
__init__.py
,新建views.py
和models.py
。 -
蓝图blueprint
-
宏伟蓝图(宏观规划)
-
蓝图也是一种规划,主要用来规划urls(路由route)
-
蓝图基本使用
-
在views.py中初始化蓝图
blue = Blueprint( 'user', __name__)
-
在
__init__
.py文件中调用蓝图进行路由注册app.register_blueprint(blueprint=blue)
-
-
-
项目文件结构及内容如下
-
__init__.py
# __init__.py : 初始化文件,创建Flask应用 from flask import Flask from .views import blue def create_app(): app = Flask(__name__) # 注册蓝图 app.register_blueprint(blueprint=blue) return app
-
views.py
# views.py : 路由和视图函数 from flask import Blueprint from .models import * # 初始化蓝图 蓝图名 blue = Blueprint('user', __name__) @blue.route('/') def index(): return 'index'
-
models.py
# model.py : 模型,数据库
-
app.py
from App import create_app # 创建app app = create_app() if __name__ == '__main__': app.run(debug=True)
-
6. route 路由
I. 路由参数
-
路由:将从客户端发送过来的请求分发到指定函数上
-
路由通过装饰器对应视图函数,并且可以接收参数,所以我们只需要在视图函数上使用装饰器即可
-
语法:
@app.route('/rule/') def hello() : return 'Hello World!' @app.route('/rule/<id>/') def hello(id): return 'Hello %s' % id
-
写法
<converter : variable_name>
-
converter
: 路由参数类型-
string
接收任何没有斜杠(‘/’)的字符串(默认) -
int
接收整型 -
float
接收浮点型 -
path
接收路径,可接收斜线(‘/’) -
uuid
只接受uuid
字符串,唯一码,一种生成规则 -
any
可以同时指定多种路径,进行限定,从列出的项目中选择一个(不能选其他值)
-
-
variable_name
:变量名
-
‖. 请求方法
-
默认支持GET,HEAD,OPTIONS,如果想支持某一请求方式,需要自己手动指定
@app.route( '/rule/' , methods=[ 'GET' , ' POST']) def hello(): return 'LOL'
-
methods
中可以指定请求方法- GET
- POST
- HEAD
- PUT
- DELETE
III. 请求和响应
-
Request
服务器在接收到客户端的请求后,会自动创建Request对象,由Flask框架创建,Request对象不可修改
-
属性:
url
:完整请求地址base_url
:去掉GET参数的URL
host_url
:只有主机和端口号的URL
path
:路由中的路径method
:请求方法remote_addr
:请求的客户端地址args
:GET请求参数form
:POST请求参数files
:文件上传headers
:请求头cookies
:请求中的cookie
-
ImmutableMultiDict
类型:- 类似字典的数据结构,与字典的区别,可以存在相同的键
args
、form
和files
都是ImmutableMultiDict
的对象 ImmutableMultiDict
中数据获取方式:dict['uname']
或dict.get('uname')
- 获取指定key对应的所有值:
dict.getlist( 'uname')
- 类似字典的数据结构,与字典的区别,可以存在相同的键
-
args
get
请求参数的包装,args
是一个ImmutableMultiDict
对象,类字典结构对象- 数据存储也是
key-value
,外层是列表,列表中的元素是元组,元组中左边是key
,右边是value
-
form
-
存储结构跟
args
一致 -
默认是接收
post
参数 -
还可以接收
PUT
,PATCH
参数
-
-
-
Response
Response:服务器返回给客户端的数据
由程序员创建,返回Response对象
-
直接返回字符串,可以返回文本内容,状态码
-
render_template
渲染模板,将模板转换成字符串(前后端不分离) -
返回
json
(前后端分离) -
自定义响应对象
a. 使用make_response(data,code)-
data返回的数据内容
-
code状态码
b.使用Response对象
-
-
-
重定向
-
redirect
redirect('http://www.qq.com')
redirect('/get_response/')
-
url_for
结合反向解析反向解析,根据函数名字,获取反向路径#
url_for("蓝图名.函数名") url_for('函数名',参数名=value)
redirect(url_for('user.get_response')) redirect(url_for('user.get_request', like=apple'))
-
-
终止执行,抛出异常
-
主动终止:
abort(code)
-
捕获异常
@app.errorhandler(404) def hello(e) : return 'LOL'