Flask视图和url
1、flask介绍
flask是用python语言基于Werkzeug工具箱编写的轻量级Web开发框架
flask本身相当于一个内核,其他几乎所有的功能都需要用到扩展,包括邮件扩展(Flask-Mail)、用户认证(Flask-Login)、数据库(Flask-SQLAlchemy),这些都需要用第三方的扩展来实现。Flask没有默认的数据库,可以使用MySql,也可以使用NoSql
其WSGI工具箱采用Werkzeug(路由模块),模板引擎采用Jinja2。这两个是Flask的核心
1、框架对比
重量级的框架:为方便业务程序的开发,提供了丰富的工具、组件,如Django
轻量级的框架:只提供web框架的核心功能,自由灵活、高度定制、如Flask、Tornado
2、常用扩展包
- Flask-SQLalchemy:操作数据库
- Flask-script:插入脚本
- Flask-migrate:管理迁移数据库
- Flask-Session:Session存储方式指定
- Flask-WTF:表单
- Flask-Mail:邮件
- Flask-Bable:提供国际化和本地化支持,翻译
- Flask-Login:认证用户状态
- Flask-OpenID:认证
- Flask-RESTful:开发REST API的工具
- Flask-Bootstrap:集成前端Twitter Bootstrap框架
- Flask-Moment:本地化日期和时间
- Flask-Admin:简单可扩展的管理接口的框架
3、Flask文档
2、Flask的使用
安装flask
pip install flask
创建flask项目
启动项目
访问项目
1. 参数说明
static_url_path:决定flask在访问静态文件时查找的路径,可以不传,默认None
static_folder:静态文件存储的文件夹,可以不传,默认static
template_folder:模板文件存储的文件夹,可以不传,默认templates
2. app.run参数
可以指定运行的主机IP地址,端口,是否开启调试模式
3. 关于debug调试模式
- 程序代码修改后可以自动重启服务器
- 在服务器出现相关的错误的时候可以将错误信息返回到前端显示
from flask import Flask
app = Flask(__name__,static_url_path='/y') # 初始化flask项目的服务,设置访问静态目录的路径
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
# 0.0.0.0代表当前系统中所有的ip地址,端口默认是5000,flask的debug模式:把错误信息显示到页面中
app.run(host='0.0.0.0',port=8080)
4. 应用程序配置参数
应用程序配置参数设置的是一个Web应用工程的相关信息,比如:数据库的连接信息、日志的配置信息、自定义的配置信息等,这样就可以集中管理项目的所有配置信息
flask将配置信息保存到了app.config属性中,该属性可以按照字典类型进行操作
- 从配置对象中加载,这样的好处是可以在项目开发中进行继承
from flask import Flask
# web项目的常量从配置对象加载
class DefaultConfig(object):
# 默认web项目的配置
USER = 'admin'
PWD = 'admin123'
app = Flask(__name__)
app.config.from_object(DefaultConfig)
@app.route('/')
def index():
print(app.config)
return 'hello world'
if __name__ == '__main__':
app.run(host='0.0.0.0',port=8080)
- 从配置文件中加载
新建一个配置文件settings.py,这个文件中的内容是:参数名=参数值
from flask import Flask
app = Flask(__name__)
# 从配置文件加载
app.config.from_pyfile('settings.py')
@app.route('/')
def index():
print(app.config['USER'])
print(app.config['PWD'])
return 'hello world'
if __name__ == '__main__':
app.run(host='0.0.0.0',port=8080)
- 从环境变量中加载
通过环境变量值找到配置文件,在读取配置文件的信息
from flask import Flask
app = Flask(__name__)
# 从环境变量中加载
app.config.from_envvar('FLASK_SETTING_PATH',silent=True) # 在企业正式运行情况下,silent选择true
@app.route('/')
def index():
print(app.config['USER'])
print(app.config['PWD'])
return 'hello world'
if __name__ == '__main__':
app.run(host='0.0.0.0',port=8080)
3、路由和URL
在应用中的url_map属性中保存着整个Flask应用的路由映射信息,可以通过读取这个属性获取路由信息
1. 获取所有的路由信息
from flask import Flask,json
app = Flask(__name__) # 初始化flask项目的服务
@app.route('/')
def hello_world():
# rules就是整个web项目的路由列表
rules = app.url_map.iter_rules()
# for rule in rules:
# print('视图函数:{},url地址:{}'.format(rule.endpoint,rule.rule))
return json.dumps({rule.endpoint: rule.rule for rule in rules})
@app.route('/test1')
def test1():
return 'test1'
@app.route('/test2')
def test2():
return 'test2'
if __name__ == '__main__':
# 0.0.0.0代表当前系统中所有的ip地址,端口默认是5000,flask的debug模式:把错误信息显示到页面中
app.run(host='0.0.0.0',port=8080)
结果
2. 动态路由(URL路径参数)
from flask import Flask
app = Flask(__name__) # 初始化flask项目的服务
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route('/user/<int(min=10):user_id>')# 动态路由:其实就是把请求参数作为路由中URL的一部分
def users(user_id):# 转换器,负责提取动态url中的id数据,并且把id数据传给视图数据
print(type(user_id))
return f'当前访问的用户是:用户{user_id}'
if __name__ == '__main__':
# 0.0.0.0代表当前系统中所有的ip地址,端口默认是5000,flask的debug模式:把错误信息显示到页面中
app.run(host='0.0.0.0',port=8080)
结果
3. 自定义转换器
redirect:重定向
url_for() :函数接收两个及以上的参数,他接收函数名作为第一个参数,接收对应URL规则的命名参数,如果还出现其他的参数,则会添加到 URL 的后面作为查询参数。
from flask import Flask,url_for,redirect
from werkzeug.routing import BaseConverter
# 自定义的转换器必须要继承当前的BaseConverter父类
class MobileConverter(BaseConverter):
# 定义一个匹配手机号码的正则表达式,regex的名字不能改变,其实是重写父类的属性
regex = r'1[3-9]\d{9}'
app = Flask(__name__,static_url_path='/ycw') # 初始化flask项目的服务
# 将自定义的转换器添加到转换器列表中
app.url_map.converters['phone'] = MobileConverter # phone是转换器的名字
@app.route('/')
def hello_world():
# url_for 的主要目的:是为了按照路由列表生成一个动态的url地址
print(url_for('phone_number',mob_num='181011100'))
print(url_for('phone_number',mob_num='18101110001',page=2))
print(url_for('phone_number',mob_num='18101110001',page='你好'))
return redirect(url_for('phone_number',mob_num='18101110001'))
@app.route('/phone/<phone:mob_num>')
def phone_number(mob_num):
return f'当前访问的手机号码是:{mob_num}'
if __name__ == '__main__':
# 0.0.0.0代表当前系统中所有的ip地址,端口默认是5000,flask的debug模式:把错误信息显示到页面中
app.run(host='0.0.0.0',port=8080)
结果
4. request请求
获取request请求参数
属性 | 说明 | 类型 |
---|---|---|
data | 记录请求的数据,并转换为字符串 | * |
form | 记录请求中的表单数据 | MutiDict |
args | 记录请求中的查询参数 | MutiDict |
cookies | 记录请求中的cookie信息 | Dict |
headers | 记录请求中的报文头 | EnvironHeaders |
method | 记录请求使用的HTTP方法 | GET/POST |
url | 记录请求的URL地址 | string |
files | 记录请求上传的文件 | * |
test1.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试请求方式和请求参数</title>
<style>
.parent{
text-align: center;
}
</style>
</head>
<body>
<div class="parent">
<h2>请求方式</h2>
<a href="/test1?userid=100&name=张三">get请求</a>
<h5>post请求</h5>
<form action="/test2" method="post" enctype="multipart/form-data">
姓名<input type="text" name="user_name"><br>
年龄<input type="text" name="user_age"><br>
上传文件:<input type="file" name="image"><br>
<input type="submit">
</form>
</div>
</body>
</html>
request请求.py
from flask import Flask,request
app = Flask(__name__) # 初始化flask项目的服务
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route('/test1',methods=['GET'])
def test1():
user_id = request.args.get('userid')
name = request.args.get('name')
print('用户id是',user_id)
print('用户name是',name)
return 'get请求成功'
# 该函数处理post请求
@app.route('/test2',methods=['POST'])
def test2():
name = request.form.get('user_name')
age = request.form.get('user_age')
print(f'name的值是{name},类型是{type(name)}')
print(f'age的值是{age},类型是{type(age)}')
# 专门处理文件上传,注意,需要在表单页面中加属性enctype="multipart/form-data"
image = request.files['image']
image.save('./static/demo.jpg')
return 'post请求成功'
if __name__ == '__main__':
# 0.0.0.0代表当前系统中所有的ip地址,端口默认是5000,flask的debug模式:把错误信息显示到页面中
app.run(host='0.0.0.0',port=8080)
结果
进入html界面
点击get请求
点击提交按钮
5. 处理响应
响应.py
from flask import Flask,redirect,jsonify,make_response,render_template
app = Flask(__name__) # 初始化flask项目的服务
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route('/demo1')
def demo1():
return redirect('http://www.baidu.com')
@app.route('/demo2')
def demo2():#响应一个json的数据
json_data={
'id':11,
'name':'张三'
}
return jsonify(json_data)
@app.route('/demo3')
def demo3(): #自定义一个响应(元组),响应由三部分:response,status,headers
return "自定义响应内容",600,{'my_parm':'python3.8'}
@app.route('/demo4')
def demo4():# 自定义一个响应(make_response函数)
resp = make_response('make_response响应内容')#响应内容
resp.status = '404 not found' # 响应状态
resp.headers['my_parm'] = 'python3.8'# 响应头
return resp
@app.route('/demo5')
def demo5():
return render_template('index.html',name='张三',age=35)
if __name__ == '__main__':
# 0.0.0.0代表当前系统中所有的ip地址,端口默认是5000,flask的debug模式:把错误信息显示到页面中
app.run(host='0.0.0.0',port=8080)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>第一个模板</title>
</head>
<body>
<h1>模板中动态的数据</h1>
{{ name }}<br>
{{ age }}<br>
</body>
</html>
结果
demo1
会直接跳转到百度界面
demo2
demo3
demo4
demo5