ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

零基础Python Web后端入门:从环境搭建到Flask API开发实战

零基础Python Web后端入门:从环境搭建到Flask API开发实战 1. 项目概述“零基础入门Web后端Python”这个标题听起来简单直接但背后藏着一条从“完全不懂”到“能做出点东西”的清晰路径。我见过太多新手一上来就扎进Django的文档里被各种概念绕得晕头转向或者跟着教程敲完代码却不知道自己在做什么。今天我想抛开那些复杂的术语和庞大的项目带你走一条更平滑、更本质的入门路线。我们不会一上来就讨论哪个框架最好而是先搞清楚Web后端到底是什么它和前端有什么区别一个最简单的请求从你的浏览器发出到服务器返回一个“Hello World”中间到底发生了什么只有把这个最基础的“黑盒”打开看明白了你后续学习任何框架比如Flask、Django还是FastAPI才会觉得豁然开朗而不是死记硬背。这篇文章就是为你一个可能连Python环境都还没配好的纯新手准备的“第一张地图”。我会假设你除了对编程有点兴趣其他一无所知然后带你一步步搭建环境、理解核心概念、并亲手写出你的第一个后端程序。我们的目标不是成为框架专家而是建立对Web后端工作方式的正确认知让你有能力去探索更广阔的世界。2. 环境搭建与工具准备迈出坚实的第一步在开始写任何代码之前一个稳定、顺手的工作环境至关重要。对于零基础的朋友我强烈建议避开那些复杂的一步到位方案比如某些庞大的集成环境。我们从最干净、最可控的方式开始。2.1 Python安装选择版本与避开陷阱首先你需要安装Python。访问Python官网你会看到两个主要版本Python 3.x 和 Python 2.x。请务必选择Python 3的最新稳定版比如3.11或3.12。Python 2早已停止维护新项目绝不应该使用它。下载安装时有一个至关重要的步骤容易被忽略勾选“Add Python to PATH”。这个选项的作用是把Python和它的包管理工具pip的路径添加到系统的环境变量里。如果不勾选你后续在命令行里输入python或pip时系统会找不到命令导致各种“不是内部或外部命令”的错误。这是新手遇到的第一个高频坑点。安装完成后验证一下。打开你的命令行工具Windows上是CMD或PowerShellmacOS/Linux上是Terminal输入python --version或python3 --version。如果能看到类似“Python 3.11.4”的版本信息恭喜你第一步成功了。再输入pip --version确认包管理工具也已就位。注意在macOS和部分Linux系统上系统可能自带了老版本的Python 2。为了区分你可能需要明确使用python3和pip3命令。我建议在入门阶段就养成使用python3和pip3的习惯避免和系统自带的Python混淆。2.2 代码编辑器轻量级利器VSCODE对于编辑器我的首推是VS Code。它轻量、免费、插件生态极其丰富对新手非常友好。不要去纠结PyCharm专业版那些高级功能在入门阶段一个能智能提示、调试方便的编辑器就足够了。安装好VS Code后你需要安装两个核心扩展Python扩展由Microsoft官方提供。这是必须的它提供了代码补全、语法高亮、调试、格式化等所有核心功能。Pylance可选但强烈推荐这是一个更强大的语言服务器能提供更精准的类型提示和代码分析。通常安装Python扩展时会推荐你一并安装。配置Python解释器在VS Code中按CtrlShiftPWindows/Linux或CmdShiftPmacOS输入“Python: Select Interpreter”然后选择你刚才安装的Python版本。这样VS Code就知道用哪个Python来运行和调试你的代码了。2.3 虚拟环境项目独立的“隔离舱”这是另一个必须养成的好习惯但也是新手最容易跳过的一步。虚拟环境可以理解为为你每个项目创建一个独立的、干净的Python工作空间。在这个空间里安装的第三方库比如Web框架只会影响当前项目不会污染你电脑上全局的Python环境。为什么要这么做想象一下你项目A需要Django 3.2项目B需要Django 4.2。如果没有虚拟环境你电脑上只能安装一个版本的Django两个项目必然有一个无法运行。虚拟环境就解决了这个问题。创建和使用虚拟环境非常简单。打开终端进入你的项目文件夹比如my_first_web_project然后执行# 创建虚拟环境环境文件会放在当前目录下的 venv 文件夹里 python -m venv venv创建完成后你需要激活这个环境Windows (CMD/PowerShell):# 在CMD中 venv\Scripts\activate.bat # 在PowerShell中 venv\Scripts\Activate.ps1macOS/Linux:source venv/bin/activate激活后你的命令行提示符前面通常会显示(venv)表示你现在正处在这个虚拟环境中。之后所有pip install的操作都只会安装库到这个虚拟环境里。要退出虚拟环境只需输入deactivate。3. Web后端核心概念初探理解数据流动的管道环境准备好了我们暂时不写代码先来聊点“思想”。很多人学后端一开始就陷入具体的语法和框架却忘了最根本的问题后端程序到底是干什么的我用一个最生活化的比喻后端就像一个餐厅的后厨。顾客点餐客户端请求你用户在餐厅小程序前端下单点了份“鱼香肉丝”。这个“下单”动作就是一个HTTP请求它包含了你要什么请求路径比如/order、怎么烹饪请求方法比如POST、以及你的桌号请求头信息等。服务员接单Web服务器小程序把订单发给餐厅服务器。这个服务器比如Nginx、Gunicorn就像前台服务员它不炒菜只负责接收订单、安排后厨、最后把菜端出来。后厨处理后端应用订单到了后厨你的Python程序。厨师你的代码逻辑看到订单后开始行动检查库存查询数据库、开始炒菜处理业务逻辑、摆盘组织数据格式。上菜HTTP响应菜做好了服务员把鱼香肉丝响应数据通常是JSON或HTML格式和一张小票响应状态码比如200表示成功404表示菜没了端给你。在这个过程中前端小程序负责展示界面和收集你的输入而后端后厨负责接收请求、处理业务逻辑、存取数据、并返回结果。它们之间通过一种叫HTTP的协议进行通信而数据通常以JSON这种轻量级的格式传递。那么Python在后厨里扮演什么角色它就是厨师手中的厨具和菜谱。Python的Web框架如Flask、Django提供了一套现成的“厨房设备”和“标准操作流程”让你不用从垒灶台开始能快速、规范地处理订单请求。我们接下来要写的第一个程序就是实现一个最简单的“后厨”它只做一件事无论顾客点什么都回应一句“Hello, World!”。4. 第一个Web后端程序从Flask开始感受脉搏在三大主流框架Django, Flask, FastAPI中我选择Flask作为入门的第一站。为什么不是功能更全的Django或性能更强的FastAPI因为Flask足够“微”、足够“裸”。它不像Django给你准备好了一整个豪华厨房你进去反而不知道从哪下手。Flask只给你一个最简单的灶台和一口锅让你能立刻开始炒菜亲眼看到“请求-响应”这个最核心的流程是如何运转的。理解了本质你再去看Django那些“高级厨电”就知道它们各自是解决什么问题的了。4.1 安装Flask与最小应用首先确保你在之前创建的虚拟环境venv中。然后在终端执行pip install flask安装完成后在你的项目目录下创建一个名为app.py的文件。我们将在这里写下所有代码。一个最基础的Flask应用长这样# 导入Flask类 from flask import Flask # 创建一个Flask应用实例。__name__参数用于确定应用的根目录。 app Flask(__name__) # 使用装饰器定义路由。当用户访问网站根路径/时触发下面的函数。 app.route(/) def hello_world(): # 这个函数返回的内容就是发送给浏览器的响应。 return Hello, World! This is my first web backend! # 程序入口。如果直接运行这个脚本而不是被导入则启动开发服务器。 if __name__ __main__: # debugTrue 开启调试模式代码修改后服务器会自动重启并且会在网页上显示详细的错误信息。仅用于开发 app.run(debugTrue)保存文件。回到终端在项目目录下运行python app.py你会看到类似这样的输出* Serving Flask app app * Debug mode: on * Running on http://127.0.0.1:5000 (Press CTRLC to quit)这说明你的本地开发服务器已经启动正在监听本机127.0.0.1的5000端口。现在打开你的浏览器访问http://127.0.0.1:5000。恭喜你应该能看到页面上显示着“Hello, World! This is my first web backend!”。4.2 核心概念拆解路由、视图函数与请求响应虽然只有十几行代码但这里包含了Web后端的几个核心概念路由Routeapp.route(/)这一行定义了一个路由。它建立了一个URL路径这里是根路径/与一个Python函数hello_world之间的映射关系。你可以把它理解为餐厅的菜单目录“/”就是首页“/about”可能就是关于我们页面。视图函数View Functionhello_world这个函数就是一个视图函数。它的职责就是处理发往对应路由的请求并返回一个响应。它是你业务逻辑发生的地方。请求Request与响应Response当你在浏览器输入网址并回车浏览器就向http://127.0.0.1:5000/发送了一个HTTP GET请求。Flask服务器收到后根据路由找到hello_world函数并执行它。函数执行后返回的字符串Flask会将其包装成一个HTTP响应包含状态码默认200 OK、响应头等发回给浏览器。浏览器接收到这个响应将其中的内容Hello, World!...渲染显示出来。你可以轻松地添加更多路由app.route(/about) def about(): return This is a simple web backend built with Flask. app.route(/user/username) def show_user_profile(username): # 动态路由username 是一个变量部分会作为参数传递给函数。 return fUser: {username}访问http://127.0.0.1:5000/about和http://127.0.0.1:5000/user/Alice试试看。第二个路由展示了如何从URL中提取变量这是实现个性化页面的基础。4.3 处理不同的HTTP方法HTTP请求不仅有路径还有方法Method。最常见的是GET获取数据和POST提交数据。默认情况下app.route只响应GET请求。我们来创建一个能处理表单提交的简单例子。首先修改app.py增加一个能显示表单和接收表单的路由from flask import Flask, request # 新增导入 request 对象 app Flask(__name__) # ... 保留之前的路由 ... app.route(/login, methods[GET, POST]) # 指定这个路由同时接受GET和POST请求 def login(): if request.method POST: # 如果请求方法是POST说明用户提交了表单。 # request.form 是一个字典包含了表单提交的数据。 username request.form.get(username) password request.form.get(password) # 警告实际应用中密码绝不能明文处理 # 这里只是演示实际应该进行哈希加密和数据库验证。 return fLogin attempted for user: {username} else: # 如果请求方法是GET说明用户只是访问这个页面我们返回一个简单的HTML表单。 return form methodpost pUsername: input typetext nameusername/p pPassword: input typepassword namepassword/p pinput typesubmit valueLogin/p /form 这里引入了request对象。它是Flask提供的全局对象代表了当前HTTP请求。通过它我们可以获取请求方法request.method、表单数据request.form、查询参数request.args、JSON数据request.json等。重启服务器如果debug模式开启保存文件后会自动重启访问http://127.0.0.1:5000/login你会看到一个简陋的登录表单。输入信息点击提交页面会显示你输入的用户名。这就是后端处理用户输入的最基本形态。5. 连接数据库让数据持久化一个只会说“Hello World”的后端是没用的。真正的应用需要存储和读取数据比如用户信息、文章内容、商品列表。这就离不开数据库。对于入门我们从最轻量的SQLite开始。它不需要安装独立的数据库服务器数据存储在一个本地文件中非常适合学习和开发小型项目。我们将使用SQLAlchemy这是一个Python中非常强大和流行的ORM对象关系映射工具。ORM允许你用Python类和对象的方式来操作数据库而不用写复杂的SQL语句极大地提高了开发效率和代码可读性。5.1 安装与配置SQLAlchemy首先安装必要的库。在虚拟环境中执行pip install flask-sqlalchemyflask-sqlalchemy是专门为Flask封装的SQLAlchemy扩展集成起来更方便。然后修改app.py配置数据库并定义一个简单的数据模型from flask import Flask, request, render_template # 稍后引入模板 from flask_sqlalchemy import SQLAlchemy import os app Flask(__name__) # --- 数据库配置 --- # 配置数据库URI。SQLite数据库文件将位于项目根目录下名为 site.db basedir os.path.abspath(os.path.dirname(__file__)) app.config[SQLALCHEMY_DATABASE_URI] sqlite:/// os.path.join(basedir, site.db) app.config[SQLALCHEMY_TRACK_MODIFICATIONS] False # 关闭对模型修改的跟踪节省资源 # 创建SQLAlchemy实例 db SQLAlchemy(app) # --- 定义数据模型Model --- # 一个模型对应数据库中的一张表 class User(db.Model): id db.Column(db.Integer, primary_keyTrue) # 主键 username db.Column(db.String(80), uniqueTrue, nullableFalse) # 用户名唯一且非空 email db.Column(db.String(120), uniqueTrue, nullableFalse) # 邮箱唯一且非空 def __repr__(self): # 定义对象的打印格式方便调试 return fUser {self.username} # 在首次请求前创建数据库表 app.before_first_request def create_tables(): db.create_all() # ... 保留之前的路由 ... # 新增一个路由用于演示用户注册和列表展示 app.route(/users, methods[GET, POST]) def handle_users(): if request.method POST: # 处理表单提交创建新用户 username request.form.get(username) email request.form.get(email) if username and email: new_user User(usernameusername, emailemail) db.session.add(new_user) # 将新用户对象添加到数据库会话 try: db.session.commit() # 提交会话将数据写入数据库 message fUser {username} created successfully! except Exception as e: db.session.rollback() # 如果发生错误如用户名重复回滚事务 message fError creating user: {e} else: message Username and email are required! else: message None # 无论是GET还是POST后都查询所有用户并展示 all_users User.query.all() # 查询User表中的所有记录 return render_template(users.html, usersall_users, messagemessage) if __name__ __main__: app.run(debugTrue)5.2 使用模板渲染HTML页面上面的代码中我们引入了一个新的函数render_template和一个尚不存在的文件users.html。在Flask中我们通常不把HTML代码直接写在Python字符串里那样太混乱了而是使用模板。模板是包含特殊占位符的HTML文件Flask会用真实的数据替换这些占位符生成最终的HTML页面。首先在项目根目录下创建一个名为templates的文件夹。Flask会自动在这个文件夹里寻找模板文件。然后在templates文件夹内创建users.html文件!DOCTYPE html html head titleUser Management/title /head body h1User List/h1 !-- 显示操作结果消息 -- {% if message %} pstrong{{ message }}/strong/p {% endif %} !-- 用户注册表单 -- h2Add New User/h2 form methodPOST label forusernameUsername:/label input typetext idusername nameusername requiredbrbr label foremailEmail:/label input typeemail idemail nameemail requiredbrbr input typesubmit valueCreate User /form hr !-- 用户列表展示 -- h2Existing Users/h2 {% if users %} ul {% for user in users %} li{{ user.username }} ({{ user.email }})/li {% endfor %} /ul {% else %} pNo users yet./p {% endif %} /body /html这个模板使用了Jinja2语法Flask默认的模板引擎{% ... %}用于控制语句如if,for。{{ ... }}用于输出变量或表达式的值。现在重启你的Flask应用访问http://127.0.0.1:5000/users。你会看到一个表单和一个空列表。填写表单并提交页面刷新后新用户就会出现在列表中。同时你会发现项目根目录下多了一个site.db文件这就是SQLite数据库文件你的数据就安全地存储在里面了。这个过程完整演示了Web后端的CRUD创建、读取、更新、删除操作中最基础的创建Create和读取Read。你通过表单POST请求提交数据后端接收并存入数据库Create然后在页面加载GET请求时从数据库读取所有数据并展示Read。6. 构建一个简单的任务管理API理解了基本的MVC模型-视图-控制器在Flask里视图函数充当了控制器角色模式和数据库操作后我们可以更进一步构建一个稍微像样点的应用一个简单的任务管理Todo List后端API。这次我们不仅支持创建和读取还支持更新和删除并且使用更符合现代前后端分离架构的JSON API格式进行通信。6.1 设计API端点RESTful API是一种设计风格它使用HTTP方法GET, POST, PUT/PATCH, DELETE来对应资源的操作。我们的任务管理API可以设计如下HTTP方法端点Endpoint描述GET/api/tasks获取所有任务列表GET/api/tasks/task_id获取单个任务的详情POST/api/tasks创建一个新任务PUT/api/tasks/task_id更新一个已存在的任务全部字段DELETE/api/tasks/task_id删除一个任务6.2 实现模型与API视图首先我们定义任务模型。修改app.py在User模型下面添加Task模型class Task(db.Model): id db.Column(db.Integer, primary_keyTrue) title db.Column(db.String(100), nullableFalse) description db.Column(db.Text, nullableTrue) is_done db.Column(db.Boolean, defaultFalse) created_at db.Column(db.DateTime, defaultdb.func.current_timestamp()) def to_dict(self): # 将模型对象转换为字典方便序列化为JSON return { id: self.id, title: self.title, description: self.description, is_done: self.is_done, created_at: self.created_at.isoformat() if self.created_at else None } def __repr__(self): return fTask {self.title}然后我们实现上述API端点。我们需要从Flask导入jsonify和request来方便地处理JSON请求和响应。from flask import Flask, request, jsonify, abort from datetime import datetime # ... (之前的app配置和User模型保持不变) ... # API: 获取所有任务 app.route(/api/tasks, methods[GET]) def get_tasks(): tasks Task.query.all() # 将任务对象列表转换为字典列表然后jsonify return jsonify([task.to_dict() for task in tasks]) # API: 获取单个任务 app.route(/api/tasks/int:task_id, methods[GET]) def get_task(task_id): task Task.query.get_or_404(task_id) # 如果找不到自动返回404错误 return jsonify(task.to_dict()) # API: 创建新任务 app.route(/api/tasks, methods[POST]) def create_task(): if not request.is_json: abort(400, descriptionRequest must be JSON) # 如果请求不是JSON格式返回400错误 data request.get_json() # 简单的数据验证 if title not in data: abort(400, descriptionTitle is required) new_task Task( titledata[title], descriptiondata.get(description, ), # 使用.get方法如果没有description则默认为空字符串 is_donedata.get(is_done, False) ) db.session.add(new_task) db.session.commit() # 返回创建成功的任务和201状态码 return jsonify(new_task.to_dict()), 201 # API: 更新任务 app.route(/api/tasks/int:task_id, methods[PUT]) def update_task(task_id): task Task.query.get_or_404(task_id) if not request.is_json: abort(400, descriptionRequest must be JSON) data request.get_json() # 更新字段 if title in data: task.title data[title] if description in data: task.description data[description] if is_done in data: task.is_done data[is_done] db.session.commit() return jsonify(task.to_dict()) # API: 删除任务 app.route(/api/tasks/int:task_id, methods[DELETE]) def delete_task(task_id): task Task.query.get_or_404(task_id) db.session.delete(task) db.session.commit() return , 204 # 删除成功返回空内容和204状态码由于我们修改了模型新增了Task表需要重新创建数据库表。最简单的方法是先删除旧的site.db文件或者使用Flask-Migrate这样的数据库迁移工具。作为演示我们可以修改create_tables函数或者直接在Python交互环境中初始化。这里我们采用一个更直接的方法在app.run()之前添加一行代码确保每次运行都重新建表注意这会导致数据丢失仅用于开发测试if __name__ __main__: with app.app_context(): db.drop_all() # 删除所有表 db.create_all() # 创建所有表 app.run(debugTrue)6.3 使用工具测试API现在我们的后端API已经准备好了。但我们没有写前端页面怎么测试呢这时候就需要用到API测试工具。最经典和方便的就是Postman或者它的开源替代品Insomnia甚至命令行工具curl也可以。以Postman为例测试GET /api/tasks新建一个请求方法选择GETURL填入http://127.0.0.1:5000/api/tasks点击Send。你应该收到一个空数组[]因为还没有任务。测试POST /api/tasks新建请求方法选择POSTURL同上。在“Body”标签页选择“raw”和“JSON”然后输入JSON内容{title: Learn Flask, description: Finish this tutorial, is_done: false}。点击Send。如果成功你会收到状态码201和创建的任务JSON对象。再次测试GET /api/tasks现在你应该能看到一个包含刚才创建任务的数组了。测试PUT /api/tasks/1方法PUTURLhttp://127.0.0.1:5000/api/tasks/1Body传入{is_done: true}。这将把第一个任务标记为完成。测试DELETE /api/tasks/1方法DELETEURL同上。成功后返回状态码204无内容。再执行一次GET列表应该为空。通过这一套操作你亲手实现了一个具备完整CRUD功能的Web API后端。它接收JSON返回JSON不关心前端是浏览器、手机App还是其他服务这就是现代前后端分离开发的基础。7. 项目部署初探从本地走向网络到目前为止我们一直在本地开发服务器app.run(debugTrue)上运行程序。这个服务器是Flask自带的性能弱、不安全绝对不可以用于生产环境。那么如何让我们的程序在真实的互联网上跑起来让其他人也能访问呢这个过程叫做部署。部署涉及多个环节对于新手我推荐从最简单的平台即服务PaaS开始比如Vercel对Python支持友好、Railway或PythonAnywhere。它们帮你处理了服务器、网络、负载均衡等复杂问题你只需要关注代码。这里以Railway为例简述流程准备生产环境文件requirements.txt: 列出项目所有依赖。在项目根目录终端执行pip freeze requirements.txt生成。Procfile(对于Railway等平台): 告诉平台如何启动你的应用。内容为web: gunicorn app:app。这表示使用Gunicorn作为WSGI服务器来运行你的appFlask实例。runtime.txt(可选): 指定Python版本如python-3.11.4。修改代码以适应生产移除或禁用调试模式app.run(debugTrue)这行代码在生产部署时不应执行。通常我们会这样写if __name__ __main__: app.run(host0.0.0.0, port5000) # 仅本地开发时手动运行生产环境通过Gunicorn等服务器启动不会执行if __name__ __main__:里面的代码。选择部署平台并操作将你的代码推送到GitHub等代码仓库。注册Railway连接你的GitHub仓库。Railway会自动检测到你的Python项目并根据requirements.txt和Procfile进行构建和部署。部署成功后Railway会给你一个唯一的URL如https://your-project-name.up.railway.app这就是你应用的公网地址。配置生产数据库本地用的SQLite文件在PaaS上可能无法持久化或性能不佳。Railway等平台提供了更可靠的数据库服务如PostgreSQL。你需要在平台面板上创建一个数据库然后获取它的连接URL一个长字符串在你的Flask配置中将SQLALCHEMY_DATABASE_URI替换成这个URL。通常平台会将这个URL放在环境变量里如DATABASE_URL你的代码应该这样读取import os app.config[SQLALCHEMY_DATABASE_URI] os.environ.get(DATABASE_URL, sqlite:///site.db)这样在本地开发时使用SQLite部署到Railway后自动使用PostgreSQL。部署成功后你的API就可以通过公网URL被访问了。这标志着你的“玩具”项目真正变成了一个可用的网络服务。8. 常见问题、调试技巧与安全须知在学习和开发过程中你一定会遇到各种错误和问题。这里记录一些最常见的情况和解决思路。8.1 高频错误与排查ModuleNotFoundError: No module named flask原因没有在正确的Python环境中安装Flask或者虚拟环境未激活。解决确认终端提示符前有(venv)然后运行pip install flask。Address already in use原因端口5000已被其他程序占用。解决停止占用端口的程序或者修改Flask运行端口app.run(debugTrue, port5001)。sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: user原因数据库表没有创建。解决确保db.create_all()被调用。可以在Python交互模式下手动执行from app import db, app with app.app_context(): db.create_all()修改模型后数据库表结构不更新原因SQLAlchemy不会自动修改已存在的表结构。解决在开发初期可以像我们之前那样粗暴地db.drop_all()再db.create_all()但这会丢失所有数据。对于正式项目必须使用数据库迁移工具如Flask-Migrate基于Alembic它可以生成迁移脚本安全地升级数据库结构。API返回乱码或中文显示问题原因响应头中没有正确设置字符编码。解决确保Flask应用配置了正确的编码或者在使用jsonify时Flask默认会使用UTF-8。如果直接返回中文字符串可以return make_response(中文内容, 200, {Content-Type: text/html; charsetutf-8})。8.2 调试技巧充分利用Debug模式app.run(debugTrue)开启后代码修改自动重启并且在浏览器中遇到错误时会显示详细的交互式调试器注意生产环境务必关闭。打印日志在关键位置使用print()或Python的logging模块输出变量值这是最直接的调试方法。使用VS Code调试器在VS Code中可以设置断点逐行执行代码查看变量状态这是最强大的调试手段。检查网络请求使用浏览器开发者工具的“网络Network”面板查看前端发送的请求和后台返回的响应详情包括URL、方法、请求头、请求体、状态码、响应体。8.3 安全须知非常重要作为入门我们的示例代码为了简洁忽略了很多安全措施。但在真实项目中安全是生命线。SQL注入我们的例子使用了ORMSQLAlchemy它通过参数化查询自动防止了SQL注入。绝对不要用字符串拼接的方式构造SQL语句如fSELECT * FROM user WHERE name {username}。跨站脚本XSS当渲染用户提供的数据到HTML页面时如果不进行转义攻击者可以注入恶意脚本。Jinja2模板默认会对变量进行HTML转义使用{{ var }}时但如果你使用|safe过滤器或直接拼接HTML就需要格外小心。跨站请求伪造CSRF我们的简单表单没有CSRF保护。在生产中对于修改数据的操作POST, PUT, DELETE必须使用CSRF令牌。Flask有扩展如Flask-WTF可以方便地集成。敏感信息泄露绝不要将密码、API密钥、数据库连接字符串等硬编码在代码中或提交到版本库。务必使用环境变量来管理。我们之前用os.environ.get(DATABASE_URL)就是很好的实践。密码存储示例中明文存储密码是极度危险的。必须使用加盐哈希如werkzeug.security中的generate_password_hash和check_password_hash来存储和验证密码。9. 下一步学习路径与框架选择走到这里你已经完成了从零到一的跨越搭建了环境、理解了HTTP和请求响应循环、用Flask写出了能处理路由和表单的程序、连接了数据库实现了CRUD、构建了JSON API、甚至了解了部署的基本概念。这已经是一个相当扎实的起点了。接下来你可以根据自己的兴趣方向深入深入Flask学习使用蓝本Blueprint组织大型项目结构集成Flask-Login处理用户认证使用Flask-Migrate管理数据库迁移探索更多的Flask扩展如Flask-Mail发送邮件Flask-Caching做缓存。学习Django如果你发现Flask需要自己组装的东西太多更喜欢“开箱即用”、功能齐全、自带管理后台的框架那么Django是你的不二之选。它的学习曲线更陡但能让你快速构建出功能复杂、结构规范的应用。从官方教程开始理解其MTV模型-模板-视图模式。尝试FastAPI如果你对高性能、异步、自动API文档Swagger UI非常感兴趣或者项目以构建微服务、数据API为主FastAPI是新兴的绝佳选择。它利用现代Python特性类型提示、Pydantic能极大地提升开发效率和运行时性能。前端搭配真正的全栈还需要了解前端。学习基本的HTML/CSS/JavaScript然后选择一个前端框架如React, Vue.js来消费你写的后端API构建交互丰富的单页面应用SPA。** DevOps与部署深化**学习使用Docker容器化你的应用使用Nginx作为反向代理学习使用真正的WSGI/ASGI服务器如Gunicorn, Uvicorn搭配进程管理工具如Supervisor, systemd进行生产环境部署。关于框架选择文章开头引用的资料已经做了很好的对比。我再提炼一下我的个人建议想快速做点小东西、理解原理、有完全的控制权从Flask开始。要快速构建一个功能完整、带管理后台、遵循“最佳实践”的传统网站如内容管理系统、电商平台直接上Django。构建高性能的API、微服务或项目严重依赖异步操作如大量I/O、WebSocket强烈考虑FastAPI。没有最好的框架只有最适合你和当前项目的框架。很多时候一个项目的不同模块也可以使用不同的框架。最重要的是你已经掌握了Web后端开发的核心思维模式——接收请求、处理逻辑、操作数据、返回响应。有了这个基础任何框架对你来说都只是一套需要学习的工具和约定而已。
返回列表