Table of Contents
前言
Flask是一个用Python编写的轻量级Web应用框架。它最初由Armin Ronacher作为Werkzeug的一个子项目在2010年开发出来。Werkzeug是一个综合工具包,提供了各种用于Web应用开发的工具和函数。自发布以来,Flask因其简洁和灵活性而迅速受到开发者的欢迎。随着Python社区的增长,Flask也得到了不断的更新和改进,成为了Python Web开发中的主流框架之一。它拥有庞大的用户和贡献者社区。
除此之外,于当下大模型大爆发的时代,它是也非常适合给企业做私有大模型场景提供web页面。对于web初学者来说一个非常值得尝试的框架。
接下来我们从web基础概念、flask安装调试、路由、模版、蓝图、数据库操作几个方面给大家介绍flask的使用。
一、Web应用基本概念
如果你是第一次解决Web应用程序,你需要首选了解一下几个概念,它们是IP地址、dns、url、http、https。
1. IP地址
IP地址是分配给网络上每个设备的唯一标识符。
它允许设备之间进行通信,分为IPv4和IPv6两种类型。
2. DNS(域名系统)
DNS是互联网上用于将域名转换为IP地址的系统。
它允许用户通过易于记忆的域名来访问网站,而不是记住复杂的数字IP地址。
3. URL(统一资源定位符)
它是互联网上资源的地址,包括网页、图片、视频等。
格式通常为:协议://域名:端口/路径?查询字符串#片段标识符。
4. HTTP(超文本传输协议)
HTTP是用于从Web服务器传输超文本到本地浏览器的协议。
它是Web通信的基础,支持客户端和服务器之间的请求和响应。
5. HTTPS(安全超文本传输协议)
HTTPS是HTTP的安全版本,通过SSL/TLS协议加密数据传输。
它保护数据免受中间人攻击和其他安全威胁。
以上这样介绍可能不够直观,举一些例子吧。
一个小姐姐去北京西单吃北京烤鸭,她要去的那家烤鸭店的名字就叫就是域名,比如我们平时在浏览器里输入的taobaoc.om。而这家烤鸭店的地支门牌号就是IP,烤鸭店名和地址都在工商局有注册,这个工商局就是DNS服务器。URL是由域名和访问资源组成的。比如taobao.com/xxxxx. 这个xxxxx就是资源,你可以理解为烤鸭店里具体的包间或卡座以及烤鸭店提供的服务。
http和https的概念你可以理解成写信和和回信的过程,http就是没有加密的信件,一个人投诉物业给有关部门写信,主管部门收到后把处理结果回信这个写信的人。https就是加密的信件,比如谍战片里的特工,它写的信都是用的暗语,即使信件传递过程有人拆开了信,也是看不懂信中的暗语的。在实际web的信传递中,http和https传递的都是具有特定格式的文本信息,浏览器发起一个请求后,服务器端会做出响应把操作结果反馈给浏览器端。这个响应可能是查询数据、删除数据或者新增数据。而服务器会返回浏览器的数据通常是可以直接渲染的html和css或是可以被间接渲染的json、xml等。
二、Flask安装和调试
2.1Flask安装
首选在pytcharm里建一个python项目,然后通过命令行切换到该项目的虚拟环境。这里如何安装和使用虚拟环境参考《Anaconda的安装和使用》,如何正确使用PyCharm创建python参考《PyCharm新手入门》。
在虚拟环境输入
pip install Flask2.2Flask调试
1. 在项目中创建一个app.py的文件。
代码如下:
from flask import Flask
app = Flask(__name__)@app.route('/')def hello_world(): usr='老王'; print(f'{usr}已经创建好了第一个flask应用!'); return 'Hello, World!'if __name__ == '__main__': app.run(debug=True)2. 设置一下flask项目的调试环境
3. 调试报错
配置好调试环境,打一个断点如下图,然后用快捷键【shift+F9】启动调
调试启动后,可以看到控制台给出一个访问地址http://127.0.0.1:5000。复制这个url地址在浏览器里打开。
浏览器打开后,如果app.py这个程序进入调试状态,按F8可以进入分步调试了。这意味着你可以正常调试flask应用了,当完成调试后,你在浏览器看到“Hello, World!”。这里恭喜你,你已经很顺利的配置环境,可以进入开发的阶段了。
然而事情的实际进展不会这么顺利。你可能会遇到环境报错,就像我遇到的情况。
刚一点击shift+F9就报错
[Errno 2] No such file or directory经查网上查找资料,发现最后问题出在安装flask版本的问题上,把flask版本调整为2.0,3就可以解决问题。查看flask版本
pip show flask发现flask版本是3.0.2,。重新安装flask
pip uninstall flaskpip install flask==2.0.3调整版本后重新再次启动,不再报错,然后再次shift+F9启动调试,这次没有报错,但是调试启动后进入helpers.py ,再点击F8,继续调试报以下错误:
d:\conda_envs\pycharm\python.exe "D:/Program Files/PyCharm Community Edition 2023.2.3/plugins/python-ce/helpers/pydev/pydevd.py" --multiprocess --qt-support=auto --client 127.0.0.1 --port 3269 --file D:\python_workspace\pythonProject\app.py已连接到 pydev 调试器(内部版本号 232.10072.31)Traceback (most recent call last): File "<frozen importlib._bootstrap>", line 1027, in _find_and_load File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 688, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 883, in exec_module File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed File "d:\conda_envs\pycharm\lib\site-packages\flask\__init__.py", line 7, in <module> from .app import Flask as Flask File "d:\conda_envs\pycharm\lib\site-packages\flask\app.py", line 28, in <module> from . import cli File "d:\conda_envs\pycharm\lib\site-packages\flask\cli.py", line 18, in <module> from .helpers import get_debug_flag File "d:\conda_envs\pycharm\lib\site-packages\flask\helpers.py", line 16, in <module> from werkzeug.urls import url_quoteImportError: cannot import name 'url_quote' from 'werkzeug.urls' (d:\conda_envs\pycharm\lib\site-packages\werkzeug\urls.py)python-BaseException经上网查找问题,发现是werkzeug的版本仍然有问题,因为werkzeug是在安装flask时同时关联安装的。我们虽然重新安装了flask,但是werkzeug仍然是旧版本,于是重新安装werkzeug
pip uninstall werkzeugpip install werkzeug==2.0.3重新调试程序,shift+F9,F8。一切正常。这里分享一个经验给大家,在我们运行python开源项目的时候,包括大模型应用像stable diffusion、llama等,我们遇到的问题80%甚至是98%都是因为安装的库文件版本有问题。所以安装python库的时候最好搞清楚库的版本,否则你会遇到数不尽的麻烦。
二、路由和视图函数
在Flask中,路由由@app.route()装饰器定义,视图函数是处理请求并返回响应的函数。
@app.route('/user/<username>')def show_user_profile(username): # 通过URL中的参数访问用户信息 return f'User {username}'
@app.route('/post/<int:post_id>')def show_post(post_id): # 通过URL中的参数访问帖子信息,确保参数是整数类型 return f'Post {post_id}'三、蓝图:
在 Flask 中,通常将不同的服务请求(即不同的路由和视图函数)组织在一个 Python 文件中是可行的,尤其是在小型应用或者学习阶段。然而,对于更大的应用或更好的代码组织,你可能希望将不同的服务请求拆分到不同的模块或蓝图中。
以下是一些组织服务请求的一般建议:
1.单一文件应用:
在小型应用中,将所有的服务请求都写在一个文件中是可以的,这样简单明了。例如:
from flask import Flaskapp = Flask(__name__)@app.route('/')def home(): return 'Home Page'
@app.route('/about')def about(): return 'About Page'
if __name__ == '__main__': app.run(debug=True)2.模块化组织:
将相关的服务请求分组到不同的模块中,例如 views.py:
from flask import Blueprint
main_bp = Blueprint('main', __name__)
@main_bp.route('/')def home(): return 'Home Page'
@main_bp.route('/about')def about(): return 'About Page'然后在主应用中导入并注册这个蓝图:
3.蓝图
请求组织到不同的蓝图中。蓝图是一种更高级别的组织方式,用于将应用拆分为可维护的模块。例如:
from flask import Blueprint
main_bp = Blueprint('main', __name__)
@main_bp.route('/')def home(): return 'Home Page'
@main_bp.route('/about')def about(): return 'About Page'主应用
from flask import Blueprint
main_bp = Blueprint('main', __name__)
@main_bp.route('/')def home(): return 'Home Page'
@main_bp.route('/about')def about(): return 'About Page'这些都是一些通用的组织代码的方式,具体选择取决于你的应用规模和组织结构。在项目变得更大时,使用模块化的方式可以更好地保持代码的可维护性。
四、表单处理:
Flask可以轻松处理表单提交。使用request对象从POST请求中获取表单数据,或使用flask-wtf等扩展库来简化表单处理。
from flask import Flask, render_template, request
@app.route('/login', methods=['POST', 'GET'])def login(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] # 处理表单提交的数据 return f'Username: {username}, Password: {password}' return render_template('login.html')五、Jinqa模版
在 Flask 中,你可以使用模板引擎来实现动态页面。模板引擎允许你在 HTML 文件中嵌入动态内容,从而根据不同的请求动态生成页面。Flask 默认使用 Jinja2 模板引擎,它提供了灵活的语法和功能,方便在 HTML 中插入动态内容。
1.安装 Jinja2:
如果你是在新的虚拟环境中,你需要安装 Jinja2:
pip install Jinja22.创建 Flask 应用:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')def home(): # 传递动态数据到模板 user = {'username': 'John', 'age': 25} return render_template('home.html', user=user)
if __name__ == '__main__': app.run(debug=True)3.创建模板文件:
在你的项目目录下创建一个名为 templates 的文件夹,然后在该文件夹中创建 home.html 文件:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Dynamic Page</title></head><body> <h1>Welcome, {{ user.username }}!</h1> <p>Your age is {{ user.age }}.</p></body></html>在这个例子中,{{ user.username }} 和 {{ user.age }} 是模板中的变量,它们将在运行时由 Flask 填充为相应的值。
六、操作数据库
1.sqlite3模块
SQLite 是一个自包含、无服务器、零配置的 SQL 数据库引擎。它是 Python 标准库的一部分,所以在大多数情况下,你不需要手动安装 SQLite 数据库,因为它已经包含在 Python 的 sqlite3 模块中。
在 Python 中,你可以使用标准库中的 sqlite3 模块来访问 SQLite 数据库:
import sqlite3# 连接到 SQLite 数据库(如果数据库不存在,会自动创建)conn = sqlite3.connect('example.db')# 创建一个游标对象cursor = conn.cursor()# 执行 SQL 语句cursor.execute('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)')# 插入数据cursor.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('Alice', 30))# 提交事务conn.commit()# 查询数据cursor.execute('SELECT * FROM users')print(cursor.fetchall())# 关闭连接conn.close()这个示例展示了如何使用 Python 的 sqlite3 模块来创建表、插入数据和查询数据。你可以直接在你的 Python 环境中运行这个代码来测试 SQLite 数据库的基本功能。
2.使用SQLAlchemy模块访问数据库
除了python自带的标准sqlite3模块,还可以通过SQLAlchemy 来处理和数据库交互,不同的是,这个模块除了sqlite还可以访问mysql等其他数据库。
使用SQLAlchemy操作数据库的步骤
安装依赖
pip install Flask SQLAlchemy创建 Flask 应用
1. 项目结构
/flask_app ├── app.py ├── models.py └── templates └── index.html2.models.py - 定义数据库模型
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class User(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), nullable=False) age = db.Column(db.Integer, nullable=False)
def __repr__(self): return f'<User {self.name}>'3 .app.py - 主应用文件
from flask import Flask, request, jsonify, render_templatefrom models import db, User
app = Flask(__name__)app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
@app.route('/')def index(): users = User.query.all() return render_template('index.html', users=users)
@app.route('/user', methods=['POST'])def create_user(): data = request.get_json() new_user = User(name=data['name'], age=data['age']) db.session.add(new_user) db.session.commit() return jsonify({'message': 'User created'}), 201
@app.route('/user/<int:id>', methods=['GET'])def get_user(id): user = User.query.get_or_404(id) return jsonify({'id': user.id, 'name': user.name, 'age': user.age})
@app.route('/user/<int:id>', methods=['PUT'])def update_user(id): data = request.get_json() user = User.query.get_or_404(id) user.name = data.get('name', user.name) user.age = data.get('age', user.age) db.session.commit() return jsonify({'message': 'User updated'})
@app.route('/user/<int:id>', methods=['DELETE'])def delete_user(id): user = User.query.get_or_404(id) db.session.delete(user) db.session.commit() return jsonify({'message': 'User deleted'})
if __name__ == '__main__': with app.app_context(): db.create_all() app.run(debug=True)4 .templates/index.html - 用于显示用户列表的简单 HTML 模板
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>User List</title></head><body> <h1>User List</h1> <ul> {% for user in users %} <li>{{ user.name }} ({{ user.age }} years old)</li> {% endfor %} </ul></body></html>相关文章
Anaconda的安装和使用分类:教程
帮助初学者,搭建codona环境
使用cline搭建python的AI编程环境分类:教程
介绍使用cline搭建python的AI编程环境
python web框架哪家强?flask、Django、FastAPI对比分类:教程
python web框架介绍