Flask框架介绍、路由系统、配置文件配置
Flask框架也是Python的同步web框架,Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架顺便总结一下Python的同步web框架有Django(大而全,适合大型网站开发)、Flask(小而精,适合小型网站开发);异步web框架有fastapi和sanic。
接下来咱详细的研究一下flask框架吧!
一、快速使用Flask框架
安装框架
pip install Flask
快速使用
from flask import Flask
app = Flask(__name__)
@app.route('/') # 装饰器的方式注册路由
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
Flask项目的目录结构
二、配置文件的配置方式
配置文件的配置方式有好几种,
- 配置方式一:直接在核心逻辑代码里面配置(测试用)
app.debug=True # 调试模式,提示信息更详细,修改代码不需要重启,自动重启
app.secret_key='dasdfasdfasd' # 秘钥,只能 放debug和secret_key
- 配置方式二:直接使用app.config设置
app.config['DEBUG']=True
app.config['SECRET_KEY']='sdfasdfasd'
- 配置方式三:跟Django的路由配置类似使用py文件(不常用)
app.config.from_pyfile("settings.py")
- 配置方式四:使用写类的方式,常用方法
app.config.from_object('settings.DevelopmentConfig')
app.config.from_object('settings.ProductionConfig')
- 配置方式五:通过环境变量配置
app.config.from_envvar("环境变量名称")
- 配置方式六:通过json文件的方式
app.config.from_json("json文件名称")
JSON文件名称,必须是json格式,因为内部会执行json.loads
- 配置方式七:字典格式(配置中心)
app.config.from_mapping({'DEBUG': True})
三、路由系统
- 路由的本质
flask是基于装饰器的,大部分都用装饰器来做,少量可以抽取到一个urls.py种、flask路由的本质是app对象的add_url_rule完成路由的注册。 - 路由的参数
rule URL规则
view_func 视图函数名称
defaults = None 默认值, 当URL中无参数,函数需要参数时,使用defaults = {'k': 'v'}为函数提供参数
endpoint = None, 路径的别名,名称,用于反向解析URL,即: url_for('名称')
methods = None, 允许的请求方式,如:["GET", "POST"]
四、通过登录的逻辑快速了解框架
- 后端代码login.py
from flask import Flask, request, render_template, redirect, session,jsonify
app = Flask(__name__)
# 要使用session,必须设置秘钥,秘钥是配置信息
app.secret_key = 'asdfasdfa33aef3aefads'
USERS = {
1:{'name':'张三','age':18,'gender':'男','text':"道路千万条"},
2:{'name':'李四','age':28,'gender':'男','text':"安全第一条"},
3:{'name':'王五','age':18,'gender':'女','text':"行车不规范"},
}
# 1 创建templates文件夹,写login.html
@app.route('/login', methods=['GET', 'POST'])
def index():
# 没有request对象,使用全局的request
# get请求,返回模板
if request.method == 'GET':
return render_template('login.html') # 新手四件套之一:返回模板
else:
# post请求,校验数据
# 取出前端传入的用户名密码,校验
username = request.form.get('username') # 等同于django的的request.POST
password = request.form.get('password')
if username == 'lqz' and password == '123':
# 登录成功,保存登录状态 重定向到跟路径 新手四件套之一:重定向
# 保存到session中,session是全局的
session['name'] = username
return redirect('/')
else:
return render_template('login.html', error='用户名或密码错误') # 注意跟django的render区分,要模板渲染的数据,直接key=value传即可
@app.route('/')
def home():
# 校验,登录成功,才能过来,不登录,重定向到登录页面
if session.get('name'): # 有值说明登录了,没有值说明没有登录
return render_template('home.html',user_dict=USERS)
else:
return redirect('/login')
@app.route('/detail/<int:pk>')
def detail(pk):
if session.get('name'): # 有值说明登录了,没有值说明没有登录
user_detail = USERS.get(pk)
return render_template('detail.html', user=user_detail)
else:
return redirect('/login')
@app.route('/test')
def test():
return jsonify([{'name':'lqz','age':19}])
if __name__ == '__main__':
app.run()
- 前端页面的代码
Home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>用户列表</h1>
<table>
{% for k,v in user_dict.items() %}
<tr>
<td>{{k}}</td>
<td>{{v.name}}</td>
<td>{{v['name']}}</td>
<td>{{v.get('name')}}</td>
<td><a href="/detail/{{k}}">查看详细</a></td>
</tr>
{% endfor %}
</table>
</body>
</html>
Login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
<p>用户名:<input type="text" name="username"></p>
<p>密码:<input type="password" name="password"></p>
<input type="submit" value="登录"> {{error}}
</form>
</body>
</html>
Detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>名字是:{{user.name}}</p>
<p>年龄是:{{user['age']}}</p>
<p>性别是:{{user.get('gender')}}</p>
<p>{{user.text}}</p>
</body>
</html>
五、通过以上小案例的总结
- 注册路由
app.route(路径,methods=[请求方式get,post])
- 新手四件套
render_template 渲染模板 跟django有区别
redirect 重定向
return 字符串 返回字符串
jsonify 返回json格式
- 请求的request对象,是全局的,直接导入使用即可,在不同视图函数中不会混乱
request.method 请求方式
request.form post请求的body体的内容转成了字典
- session 全局的,直接导入使用即可,一定要指定秘钥
app.secret_key = 'asdfasdfa33aef3aefads'
放值:session['name']='lqz'
取值:session.get('name')
- 模板的渲染
兼容django的dtl
更强大,可以加括号,字典可以.get .values() .items()
{% for %}
- 转换器
@app.route('/detail/<int:pk>')