Flask新手入门(一)

发布于:2024-06-29 ⋅ 阅读:(15) ⋅ 点赞:(0)

前言

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 Flask

2.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 flask
pip 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_quote
ImportError: 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 werkzeug
pip 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 Flask
app = 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:

# 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.蓝图

请求组织到不同的蓝图中。蓝图是一种更高级别的组织方式,用于将应用拆分为可维护的模块。例如:

# main_blueprint.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'

主应用

# main_blueprint.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'

这些都是一些通用的组织代码的方式,具体选择取决于你的应用规模和组织结构。在项目变得更大时,使用模块化的方式可以更好地保持代码的可维护性。

四、表单处理:

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 Jinja2

2.创建 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.html

2.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_template
from 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>

网站公告

今日签到

点亮在社区的每一天
去签到