1-Flask相关知识点
- Flask是一个使用Python编写的轻量级Web应用框架。
- 安装: pip install flask
- 中文文档
from flask import Flaskapp = Flask(__name__)@app.route("/")
def index():return "Hello, World!"if __name__ == '__main__':app.run()
1.flask路由
- 将用户请求的 URL 映射到对应的视图函数
1.1基本路由
1.1.1 定义路由
- 在 Flask 中,使用 @app.route() 装饰器来定义路由。这个装饰器将一个 URL 路径映射到一个视图函数。
- 示例代码:
from flask import Flaskapp = Flask(__name__)@app.route('/')
def home():return 'Hello, World!'
在这个例子中,当用户访问应用的根路径(/)时,home 函数会被调用,并返回字符串 ‘Hello, World!’
1.1.2 多个路由
- 你可以定义多个路由,每个路由对应一个视图函数。
- 示例代码:
@app.route('/about')
def about():return 'This is the about page.'@app.route('/contact')
def contact():return 'Contact us at contact@example.com'
在这个例子中,访问 /about 会显示 ‘This is the about page.’,访问 /contact 会显示 ‘Contact us at contact@example.com’
1.2 动态路由
1.2.1 变量规则
- Flask 允许在路由中使用变量规则,这样可以捕获 URL 中的动态部分。
- 示例代码:
@app.route('/user/<username>')
def show_user_profile(username):return f'User {username}'
1.2.2 转换器
- Flask 提供了几种转换器,用于指定动态部分的类型。常见的转换器包括:
- string(默认):接受任何不包含斜杠 / 的文本。
- int:接受整数。
- float:接受浮点数。
- path:接受包含斜杠 / 的文本。
- 示例代码:
@app.route('/post/<int:post_id>')
def show_post(post_id):return f'Post {post_id}'
在这个例子中,int:post_id 表示 post_id 必须是一个整数。如果用户访问 /post/123,post_id 的值为 123,返回 ‘Post 123’。
1.3 路由的 HTTP 方法
1.3.1 默认方法
- 如果没有指定 HTTP 方法,Flask 默认只支持 GET 方法。
- 示例代码:
@app.route('/login')
def login():return 'Login Page'
在这个例子中,只有通过 GET 方法访问 /login 时,login 函数才会被调用。
1.3.2 指定方法
- 可以通过 methods 参数指定路由支持的 HTTP 方法。
- 示例代码:
@app.route('/login', methods=['GET', 'POST'])
def login():if request.method == 'POST':return 'Login Successful'else:return 'Login Page'
在这个例子中,/login 路由支持 GET 和 POST 方法。如果通过 POST 方法访问 /login,返回 ‘Login Successful’;如果通过 GET 方法访问,返回 ‘Login Page’
2.自定义转换器
- 允许你定义自己的规则来解析 URL 中的动态部分。
- 默认情况下,Flask 提供了一些内置的转换器(如 string、int、float 等),但有时候这些内置转换器可能无法满足你的需求。
- 这时,你可以通过自定义转换器来实现更复杂的匹配逻辑。
2.1 自定义转换器的定义
自定义转换器需要继承 werkzeug.routing.BaseConverter 类,并实现以下方法:
__init__(self, url_map)
- 初始化方法,通常用于设置一些默认值或参数。
to_python(self, value)
- 将 URL 中的动态部分转换为 Python 可以处理的类型。这个方法在 Flask 调用视图函数时被调用。
to_url(self, value)
- 将 Python 中的值转换为 URL 中的字符串。这个方法在使用 url_for 函数生成 URL 时被调用。
from flask import Flask
from werkzeug.routing import BaseConverter# 1.自定义转换器
class RegexConverter(BaseConverter):def __init__(self, url_map, regex):# 调用父类的方法super(RegexConverter, self).__init__(url_map)self.regex = regexdef to_python(self, value):# 父类的方法 功能已经实现好了print('to_python方法被调用')return valuedef to_url(self, value):# 父类的方法 功能已经实现好了print('to_url方法被调用')return value# 2.注册转换器(将自定义的转换器 添加到flask应用中)
app = Flask(__name__)
app.url_map.converters['re'] = RegexConverter# 3.使用自定义转换器
@app.route('/index/<re("123"):value>')
def index(value):print(value)return 'ok'if __name__ == '__main__':app.run()
3.request对象
它提供了对请求数据的访问,包括请求方法、请求头、查询参数、表单数据、文件上传等。通过 request 对象,你可以获取客户端发送的所有信息,并根据这些信息进行相应的处理。
3.1 request 对象的主要属性和方法
3.1.1 请求方法
- request.method:获取请求的 HTTP 方法(如 GET、POST、PUT、DELETE 等)。
- 示例代码:
from flask import Flask, requestapp = Flask(__name__)@app.route('/example', methods=['GET', 'POST'])
def example():if request.method == 'POST':return 'This is a POST request'else:return 'This is a GET request'
3.1.2 请求路径
- request.path:获取请求的路径部分。
- 示例代码:
@app.route('/example/<path:subpath>')
def example(subpath):return f'Path: {request.path}'
3.1.3 查询参数
- request.args:获取 URL 中的查询参数,返回一个 ImmutableMultiDict 对象。
- 示例代码:
@app.route('/search')
def search():query = request.args.get('q', '') # 获取查询参数 'q',默认值为空字符串return f'Search query: {query}'
3.1.4 表单数据
- request.form:获取表单数据,返回一个 ImmutableMultiDict 对象。
- 示例代码:
@app.route('/login', methods=['POST'])
def login():username = request.form['username']password = request.form['password']return f'Username: {username}, Password: {password}'
3.1.5 请求头
- request.headers:获取请求头,返回一个 EnvironHeaders 对象。
- 示例代码:
@app.route('/headers')
def headers():user_agent = request.headers.get('User-Agent', '')return f'User-Agent: {user_agent}'
3.1.6 请求体
- request.data:获取请求体的原始数据,返回一个字节串。
- 示例代码:
@app.route('/data', methods=['POST'])
def data():raw_data = request.datareturn f'Raw data: {raw_data}'
- request.json:如果请求体是 JSON 格式,可以直接通过 request.json 获取解析后的 JSON 数据。
- 示例代码:
@app.route('/json', methods=['POST'])
def json():data = request.jsonreturn f'JSON data: {data}'
3.1.7 文件上传
- request.files:获取上传的文件,返回一个 ImmutableMultiDict 对象。
- 示例代码:
@app.route('/upload', methods=['POST'])
def upload():file = request.files['file']if file:filename = file.filenamefile.save(f'uploads/{filename}')return f'File uploaded: {filename}'return 'No file uploaded'
4.重定向和错误
4.1 重定向
- 要将用户重定向到另一个端点,请使用 redirect() 函数
from flask import abort, redirect, url_for@app.route('/')
def index():return redirect(url_for('login'))@app.route('/login')
def login():return 'ok'
4.2 错误
4.2.1 abort()
- 要使用错误代码提前中止请求,请使用 abort() 函数
from flask import abort, redirect, url_for@app.route('/')
def index():return redirect(url_for('login'))@app.route('/login')
def login():abort(401)this_is_never_executed()
4.2.2 errorhandler()
- 自定义错误页面,可以使用 errorhandler() 装饰器
from flask import render_template@app.errorhandler(404)
def page_not_found(error):return render_template('page_not_found.html'), 404
5.响应格式
5.1 make_response()
- 在视图内部获取生成的响应对象
import jsonfrom flask import Flask, make_responseapp = Flask(__name__)@app.route('/index')
def index():data = {"name": "暂时"}response = make_response(json.dumps(data, ensure_ascii=False))response.mimetype = 'application/json'return responseif __name__ == '__main__':app.run()
5.2 jsonify()
- Json数据
from flask import Flask, make_response, jsonifyapp = Flask(__name__)
app.config["JSON_AS_ASCII"] = False@app.route('/index')
def index():data = {"name": "暂时"}# response = make_response(json.dumps(data, ensure_ascii=False))# response.mimetype = 'application/json'# return responsereturn jsonify(data)if __name__ == '__main__':app.run()
6.模版
- Flask 默认使用 Jinja2 作为模板引擎。
6.1 模板文件的位置
- 默认情况下,Flask 会在应用的根目录下查找一个名为 templates 的文件夹。你可以将所有的模板文件放在这个文件夹中。例如:
my_flask_app/
│
├── app.py
├── templates/
│ ├── index.html
│ └── about.html
└── static/
└── style.css
6.2 渲染模板
- 在 Flask 中,你可以使用 render_template 函数来渲染模板。这个函数会自动查找 templates 文件夹中的模板文件,并将模板中的变量替换为实际的值。
- 示例代码
from flask import Flask, render_templateapp = Flask(__name__)@app.route('/index')
def index():data = {'name': '张三','age': 18}return render_template('index.html', data=data)if __name__ == '__main__':app.run()
- templates/index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
hello word
</body>
</html>
6.3 模板中的变量和表达式
Jinja2 模板引擎支持多种变量和表达式,以下是一些常见的用法:
6.3.1 变量
<p>Hello, {{ name }}!</p>
6.3.2 条件语句
{% if user.is_authenticated %}<p>Welcome back, {{ user.name }}!</p>
{% else %}<p>Please log in.</p>
{% endif %}
6.3.3 循环
<ul>{% for item in items %}<li>{{ item }}</li>{% endfor %}
</ul>
6.3.4 过滤器
Jinja2 提供了许多内置的过滤器,用于对变量进行格式化或转换。例如:
<p>{{ message|upper }}</p>
<p>{{ number|format('%.2f') }}</p>
7.flask表单
处理表单数据涉及到接收、验证和处理用户提交的表单。Flask 提供了基本的表单处理功能,但通常结合 Flask-WTF 扩展来简化表单操作和验证。
- 基本表单处理:使用 request.form 获取表单数据。
- 使用 Flask-WTF:结合 WTForms 进行表单处理和验证,简化表单操作。
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField # 类型
from wtforms.validators import DataRequired, EqualTo # 验证数据不能为空 验证数据是否相同app = Flask(__name__)
app.config['SECRET_KEY'] = 'dhuifh' # 用于 CSRF 保护# 定义表单模型类
class Register(FlaskForm):username = StringField(label='用户名', validators=[DataRequired('用户名不能为空')])password = PasswordField(label='密码', validators=[DataRequired('密码不能微控')])password2 = PasswordField(label='在输入一次密码', validators=[DataRequired('密码不能微控'), EqualTo('password')])submit = SubmitField(label='提交')@app.route('/register', methods=['GET','POST'])
def register():# 创建表单对象form = Register()if request.method == 'GET':return render_template('register.html', form=form)elif request.method == 'POST':# validate_on_submit 验证器 表单传过来的数据如果都是正确的就会往后执行if form.validate_on_submit():username = form.username.datapassword = form.password.datapassword2 = form.password2.dataprint(username, password, password2)else:print("验证失败")return render_template('register.html', form=form)if __name__ == '__main__':app.run()
templates/register.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<form action="" method="post">{{ form.username.label }}{{ form.username }}<br>{{ form.password.label }}{{ form.password }}<br>{{ form.password2.label }}{{ form.password2 }}<br>{{ form.submit }}
</form></body>
</html>
8.flask数据库
中文文档地址
8.1 安装依赖
pip install flask-sqlalchemy
pip install mysql-connector-python
8.2 配置数据库
from flask import Flask
from flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)# 配置数据库 URI
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
# app.config['SQLALCHEMY_DATABASE_URI'] = mysql+pymysql://username:password@host:port/dbname
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False# 初始化 SQLAlchemy
db = SQLAlchemy(app)
8.3 定义模型
-
db.Model:所有模型类需要继承自 db.Model。
-
db.Column:定义模型的字段,指定字段的类型、是否为主键、是否唯一、是否可以为空等属性。
class Role(db.Model):"""角色表达"""__tablename__ = 'role'id = db.Column(db.Integer, primary_key=True)name = db.Column(db.String(32), unique=True)class User(db.Model):"""用户表"""__tablename__ = 'user'id = db.Column(db.Integer, primary_key=True)name = db.Column(db.String(128), unique=True)password = db.Column(db.String(128))# 表关系 外键ForeignKeyrole_id = db.Column(db.Integer, db.ForeignKey('Role.id'))
8.4 创建表
if __name__ == '__main__':# 初始化数据库with app.app_context():# 清除所有表db.drop_all()# 创建所有表db.create_all()# 创建角色role1 = Role(name="admin")db.session.add(role1) # session记录到对象任务中db.session.commit() # 提交任务role2 = Role(name="admin2")db.session.add(role2)db.session.commit()# 创建用户user1 = User(name="zhangsan", password="123456", role_id=role1.id)user2 = User(name="lisi", password='123456', role_id=role1.id)user3 = User(name="wangwu", password='123456', role_id=role2.id)db.session.add_all([user1, user2, user3])db.session.commit()