ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Flask+Python+MySQL电子商城项目源码解析与部署实践

Flask+Python+MySQL电子商城项目源码解析与部署实践 简介在Web开发中Flask作为轻量级Python框架凭借灵活性和简洁性广受开发者青睐常与MySQL配合构建动态网站。理解路由、模板渲染、数据库ORM等核心原理是搭建完整应用的基础。通过一个电子商城项目可以串联用户、商品、购物车、订单等核心业务掌握从数据库设计到部署的完整流程。本文基于一套FlaskPythonMySQL的商城源码解析其目录结构、SQL表关联、购物车与Session机制并分享部署中的常见问题与安全加固建议帮助读者快速上手全栈项目开发。 我先说下拿到这套“基于flaskpythonMysql的电子商城项目源码(含sql和说明).zip”之后的整体感受这就是一个很典型的 Flask 全栈练手项目把电商网站最核心的用户、商品、购物车、订单这几条线都串起来了同时附带完整的 SQL 初始化和一份说明文档对刚学完 Python 语法、想接触真实 Web 项目的人来说是非常合适的过渡素材。我花了两个晚上把整个压缩包从解压到跑通、再到把每个文件都过了一遍这篇文章就把我梳理出来的代码结构、SQL 设计、部署流程和踩坑记录都写出来希望能帮你少走弯路。1. 项目整体设计与源码结构拆解1.1 拿到压缩包后我第一时间做了什么解压之后第一件事不是急着看代码而是先看目录。一个 Flask 项目能不能快速上手目录规不规范比功能多不多更重要。这套源码解压出来大概是这样project/ │ ├── app.py # 应用入口路由注册和启动都在这 ├── config.py # 数据库连接配置、密钥等 ├── requirements.txt # 依赖清单 ├── README.md # 说明文档 │ ├── models.py # 数据模型对应数据库表结构 ├── views.py # 视图函数处理业务逻辑和页面跳转 │ ├── templates/ # HTML 模板目录 │ ├── base.html │ ├── index.html │ ├── login.html │ ├── register.html │ ├── cart.html │ ├── order.html │ └── admin/ │ └── dashboard.html │ ├── static/ │ ├── css/ │ ├── js/ │ └── images/ │ ├── sql/ │ └── shop.sql # 建库建表 初始化数据 │ └── utils/ └── common.py # 通用工具函数这个结构有明显的分层意识入口、配置、模型、视图、模板、静态资源、SQL脚本分离得很清楚。很多初学者写 Flask 项目喜欢把所有代码堆在一个 app.py 里几百行甚至上千行那类项目我一般不建议拿来做学习范本因为逻辑搅在一起改一个功能容易带崩另一个。这套源码虽然不是完美的大型项目架构但作为中小型商城的代码组织方式已经足够清晰了。默认入口文件叫 app.py直接python app.py就能启动这符合 Flask 开发者最常见的习惯。如果你的机器上已经装了 Python 和 MySQL按照 README 里的顺序操作基本十分钟内可以看到首页。1.2 为什么这套结构适合拿来练手和二次开发先说选型层面的逻辑。Flask 是一个微框架它不像 Django 那样把 ORM、Admin、认证全都内置好而是把选择权交给开发者。这就导致一个非常现实的问题用 Flask 写小项目很快但项目一旦变大数据库操作、模板渲染、路由管理如果没有统一组织代码会迅速腐化。这套商城源码做了一个折中的做法保留 Flask 的轻量特性同时手动划分 models、views、templates 三层本质上是在向 Django 的 MVT 模式靠拢。从二次开发角度讲这种结构最友好的地方在于想加一个新页面只需在 views.py 里写一个路由函数然后在 templates 里加一个 HTML 文件不需要动其他模块想加一张新表先在 sql 里写好建表语句再在 models.py 里补一个类两边字段对应上就行想改前端样式静态文件都在 static 目录跟后端逻辑互不干扰。我见过太多练手项目做到一半就放弃的情况大部分不是因为功能太难而是因为代码堆成一团越改越不敢改。这套源码把“改哪里”这件事变得很直观这是它作为学习素材最大的价值。2. SQL 设计从建库到商品数据初始化2.1 建库建表前必须确认的三件事这套源码附带的 sql/shop.sql 是整个项目的“地基”。数据库要是建不对代码跑得再欢也没用。导入 SQL 之前你需要确认三件事MySQL 服务是否已经启动、字符集是否能正常显示中文、目标数据库名是否和 config.py 里配置的一致。我看了下 shop.sql开头部分通常会包含类似这样的语句CREATE DATABASE IF NOT EXISTS shop DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE shop; SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;utf8mb4这个字符集必须要强调一下。早期很多教程用utf8但 MySQL 的utf8是阉割版最多只支持3字节遇到 emoji 或者生僻字就会报错或者存成乱码。现在做电商类项目用户昵称、收货地址、商品描述里出现特殊字符的概率很高直接上utf8mb4是最稳妥的。另外SET FOREIGN_KEY_CHECKS 0这个命令的作用是临时禁用外键检查这样在建表时可以任意调整表的创建顺序不用纠结先建主表还是先建从表等所有表都建好之后再恢复检查。还有一个容易被忽略的细节DROP TABLE IF EXISTS。初始化脚本里一般会把旧的同名表先删掉再重建这是为了让脚本可以重复执行。但如果你在正式环境或者已经有数据的库上执行这个脚本数据会全部清空所以跑导入命令之前一定要看清楚当前连的是哪个库。2.2 商品、用户、订单三张核心表是怎么关联的商城的核心表就那么几张用户表、商品表、购物车表、订单表、订单详情表。我拆开 shop.sql 看了一下这套源码的表设计遵循了最常见的电商数据库范式大致可以整理成下面几条关系线用户与订单用户表user通常有 id、username、password、email、create_time 等字段。下单时需要一个外键把订单关联到用户头上常见做法是在订单表orders里存 user_id通过外键约束指向用户表的主键。这样查询“某个用户的所有订单”就只需要一条 WHERE 语句。商品与订单详情商品表product有 id、title、price、stock、image 等字段。订单详情表order_item里同时存 order_id 和 product_id外加购买数量。为什么要单独搞一张订单详情表因为一个订单可能包含多个商品如果只在订单表里存一个商品 ID那“一个订单买了三样东西”这种场景就没法表达了。购物车与商品购物车表cart关联 user_id 和 product_id外加一个 quantity 字段表示数量。这里有个技术选型细节购物车到底应不应该落库很多 Flask 教程为了省事直接用 Session 存购物车数据关闭浏览器就没了。这套源码选择了落库方案好处是用户换设备或者清缓存后购物车还在更接近真实商城的行为代价是每次加入购物车都要写一次数据库对高并发场景不友好。对于学习项目来说落库是更合理的方案你能借此理解关系型数据库在真实电商系统里是怎么参与业务流转的。看完表结构之后我建议你顺手练习几个 SQL 查询这对理解代码里的 ORM 操作很有帮助。比如查询某个用户的订单总金额就需要把订单表、订单详情表、商品表三张表 JOIN 起来查询库存不足的商品可以用 WHERE stock 某阈值统计每个分类下的商品数量可以用 GROUP BY。如果这些 SQL 你都能不看答案写出来那说明这套源码的表设计你已经真正吃透了。2.3 初始化数据一套能直接演示功能的基础数据sql 脚本里除了建表语句通常还会附带一批 INSERT 语句。千万不要小看这些初始化数据它们是项目能开箱即用的关键。我见过不少开源项目只给表结构不给数据结果启动之后后台空空如也连商品都没法添加想测试下单流程还得自己造数据非常影响体验。这套源码的初始化数据包含两类第一类是管理员账号和测试用户。管理员账号通常写入 user 表时有一个 role 或 is_admin 字段标记方便后台页面做权限判断。测试用户的密码在 SQL 里一般不会存明文而是存哈希值。如果你看到类似pbkdf2:sha256:...或者$2b$12$...这样的字符串说明密码经过了加密处理你没法直接从数据库里反推出原始密码但可以用代码里注册接口重新创建一个账号来测试。第二类是商品数据。一般会插入十几条测试商品覆盖手机数码、服饰鞋包、家居生活等常见分类每条商品都有价格、库存、图片路径、描述等字段。这样你启动项目后首页就能正常展示商品列表点击商品详情页也能看到完整信息不需要手工去后台补录。我建议你导入 SQL 之后用 Navicat、DBeaver 或者命令行客户端进去看一眼这几张表的数据量确认商品表有数据、用户表有数据再进行下一步代码调试。3. Flask 核心代码路由、模板、Session 购物车3.1 路由与视图函数Flask 怎么把网址和代码对应起来Flask 最核心的概念之一就是路由。简单说路由就是建立一个“网址路径”到“Python 函数”的映射关系。用户在浏览器里访问http://127.0.0.1:5000/product/3Flask 框架会解析出路径/product/3然后找到对应的视图函数把参数 3 传进去函数执行完后返回一个 HTML 页面或者 JSON 数据。这套源码的 views.py 里典型的代码长这样from flask import render_template, request, redirect, url_for, session from models import Product, User, Cart, Order from app import app, db app.route(/) def index(): products Product.query.all() return render_template(index.html, productsproducts) app.route(/product/int:product_id) def product_detail(product_id): product Product.query.get_or_404(product_id) return render_template(product_detail.html, productproduct)几行代码就完成了首页展示和商品详情页这两个最基础的功能。这里面有两个值得注意的写法第一是int:product_id这个路径参数转换器。它告诉 Flask这里的参数必须是整数如果不是整数就直接返回 404这样能避免用户访问/product/abc时程序报 TypeError。这是一个很好的参数校验习惯很多新手容易忽略等到线上被人用非法参数刷接口时就傻了。第二是get_or_404。它的作用是根据主键查数据如果查不到就直接返回 404 页面不需要你手动判断返回值是否为空。这种写法非常简洁既保证了页面的完整性又省掉了冗余的判断逻辑。这套源码里的购物流程核心是下面几个路由组成的状态机首页浏览商品 - 商品详情页点击加入购物车 - 购物车页面修改数量或删除 - 结算生成订单 - 支付回调修改订单状态。每个路由对应一个 Flask 视图函数函数内部负责验证参数、操作数据库、渲染模板或跳转页面。把这条链路走通你对 Web 应用的请求-响应模型就有非常直观的理解了。3.2 模板渲染与 Jinja2HTML 里怎么写 Python 逻辑Flask 默认使用 Jinja2 作为模板引擎。它的核心思路是在 HTML 文件里预留一些“洞”由 Python 代码计算好数据后填进去最终生成完整的 HTML 返回给浏览器。看一下 templates/index.html 的典型写法{% for product in products %} div classproduct-card img src{{ product.image }} alt{{ product.title }} h3{{ product.title }}/h3 p classprice¥{{ product.price }}/p a href{{ url_for(product_detail, product_idproduct.id) }}查看详情/a /div {% endfor %}{% for %}和{% endfor %}是 Jinja2 的循环控制语句{{ product.title }}是变量输出语法。这里有个经验想分享模板里尽量只做展示逻辑不要写复杂的业务计算。有些初学者为了方便直接模板里写一堆 if-elif-else 处理价格折扣、库存状态、用户权限结果模板变得比 Python 代码还难维护。正确的做法是在视图函数里先把数据加工好模板只负责“把已经准备好的值显示出来”至于这个值是打折后价格还是普通价格应该在 Python 代码里算好再传给模板。另外base.html这个父模板在这个项目里起了很重要的作用。它把页面公共部分——导航栏、页脚、CSS/JS 引用——都写在里面然后通过{% block content %}{% endblock %}留出子模板的填充区域。子页面只需要继承 base.html 并重写 content 块就可以生成一个完整页面。这是 Jinja2 的模板继承机制可以极大减少重复代码也是你后面自己写项目时最值得养成的模板组织习惯。3.3 购物车与 Session登录状态和购物车数据怎么存购物车是实现电商逻辑绕不开的模块。这套源码选择把购物车落库但登录状态和临时数据是存在 Session 里的。先讲 Session。Flask 提供的 Session 本质上是把数据加密后存在浏览器的 Cookie 里客户端每次请求时把 Cookie 带回来服务端解密后就能读取。最典型的使用场景是“记住当前登录的用户是谁”。登录成功后代码会执行类似这样的操作session[user_id] user.id session[username] user.username之后在任何视图函数里只要检查session.get(user_id)是否存在就能判断用户是否已登录。这个机制非常好用但也埋了一个坑如果app.secret_key是硬编码写在 config.py 里的固定字符串攻击者一旦获取到这个密钥就可以伪造任意用户的 Session相当于拿到了所有账号的后门。所以 secret_key 在真实项目中一定要从环境变量读取并且定期轮换。这套源码作为学习项目可能为了省事写了一个固定的值但你在部署到公网之前务必改掉。再讲购物车落库。购物车表的操作可以拆成三个基本动作加入购物车先检查该用户是否已经把该商品加入过购物车如果已存在则只更新数量如果不存在才插入新记录。这个判断用 ORM 写起来就是先 query 再 update 或 insert。修改数量用户在前端点击“”“-”按钮通过 POST 请求把 cart_id 和新数量传给后端。后端要先确认这个购物车记录确实属于当前登录用户再执行更新否则会出现越权操作——用户 A 直接攻击接口把用户 B 的购物车数量改掉。删除条目执行 delete 操作后需要重新统计购物车商品总数和总金额再返回给前端刷新显示。这套源码把购物车逻辑写到了落库方案里你在阅读时重点看它处理“并发”和“越权”这两个问题的方式。虽然是学习项目但如果有意识地加入这两重校验代码的可信度会高很多。3.4 用户注册、登录与密码存储的安全细节用户模块是电商系统里最容易出安全问题的地方尤其是注册和登录接口。这套源码在密码存储上我注意到它是用 Werkzeug 自带的密码哈希工具来处理的这是非常正确的做法。from werkzeug.security import generate_password_hash, check_password_hash # 注册时生成哈希 hashed_password generate_password_hash(password) # 登录时校验 check_password_hash(user.password, password)这里的原理值得展开讲一下。哈希算法是单向的从明文密码计算出哈希值很容易但要从哈希值反推出明文密码在计算上是不可能做到的事情。而且generate_password_hash在每次生成时还会自动加入一个随机盐值这意味着即使用户设置了相同密码两次生成的哈希值也完全不同。这个机制避免了“所有密码相同的用户拥有相同哈希”这个致命问题也可以有效防御彩虹表攻击。如果你在别的开源项目里看到密码明文存储或者用 MD5、SHA1 这种不带盐的哈希直接存密码就要高度警惕了。MD5 加不加盐都已经被 GPU 暴力破解到可以快速撞库放在真实网站上是分分钟被脱裤的下场。Werkzeug 是 Flask 的底层依赖所以直接用这个工具函数不需要额外安装任何包非常方便。登录后的会话管理还有一个细节登录成功之后要调session.clear()或者重新session.update()防止用户注册时遗留的临时字段污染登录状态。有些老项目踩过这种坑用户在注册页面填写了某个字段存进 Session登录时没有清理结果每次请求都会带着这个脏数据导致页面显示异常。4. 本地跑通全流程从 MySQL 安装到浏览器看到首页4.1 MySQL 准备建库与导入 SQL 的完整步骤在写代码之前先把数据库搞定。我知道很多初学者卡在这一步因为 MySQL 的安装和配置在某些环境下确实有不少坑尤其是用绿色版或者直接改配置文件的情况。这里我推荐一套我自己试过很多次比较稳的流程第一步下载并安装 MySQL Community Server。安装过程中会让你设置 root 用户的密码一定要记好后面 config.py 里要填。如果你安装的是 MySQL 8.x默认的认证插件是 caching_sha2_password某些老版本的 PyMySQL 连接时会报错这时候只需要在连接配置里指定auth_pluginmysql_native_password或者在 MySQL 里执行对应的 ALTER USER 语句把插拔改回来。第二步打开命令行工具登录 MySQL。命令是mysql -u root -p输入密码进入交互界面执行source /你的绝对路径/sql/shop.sql;这一步会自动创建数据库和数据表并插入初始化数据。执行完后用USE shop; SHOW TABLES;确认一下表是否存在再用SELECT COUNT(*) FROM product;看商品数据是否导入成功。第三步验证连接配置。打开项目的 config.py检查以下几行app.config[SQLALCHEMY_DATABASE_URI] mysqlpymysql://root:你的密码127.0.0.1:3306/shop?charsetutf8mb4 app.config[SECRET_KEY] 一个足够长的随机字符串这里有一个最常见的坑数据库密码里如果包含、#、?这些特殊字符直接拼接在连接字符串里会被解析器误判导致连接失败。解决方法是把特殊字符做 URL 编码比如写成%40。另外127.0.0.1和localhost在某些环境下表现不同如果遇到连接死活不上可以试试把localhost改成127.0.0.1或者反过来。4.2 Python 虚拟环境与依赖安装用 venv 还是 conda很多初学者拿到项目源码的第一个动作就是pip install -r requirements.txt装完之后系统环境被搞得一团乱。我的建议是不管你是用原生 Python 还是 Anaconda都要为这个项目单独建一个虚拟环境。用 Python 自带的 venv 的话命令是python -m venv venvWindows 下激活环境venv\Scripts\activatemacOS / Linux 下激活环境source venv/bin/activate如果你用的是 Anaconda可以用 conda 建环境conda create -n flask_shop python3.9 conda activate flask_shop激活环境后再执行pip install -r requirements.txt为什么一定要用虚拟环境核心原因只有一个依赖隔离。这个项目依赖的 Flask 版本可能是 2.x而你可能在另一个项目里用了 Flask 3.x两边如果用同一个全局环境升级一个就会破坏另一个。虚拟环境相当于给每个项目一个独立的“包仓库”互相不干扰。这件事不是你写小项目时体会不到等你同时维护两三个项目的时候就深有感触了。我特意看了一眼 requirements.txt这套商城项目的依赖一般会包含这几个FlaskWeb 框架本体PyMySQL连接 MySQL 的驱动Flask-SQLAlchemy数据库 ORMWerkzeug密码哈希和 WSGI 工具Flask 依赖它Jinja2模板引擎Flask 依赖它。如果你在安装过程中遇到网络超时或者下载慢可以换成国内镜像源pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple装完之后可以用pip list检查关键包版本确保 Flask-SQLAlchemy 和 Flask 之间没有版本冲突。我踩过的一个坑是 Flask-SQLAlchemy 3.x 配 Flask 2.x 的时候初始化方式有细微区别如果 README 里说明的是旧版写法可能需要小改代码才能跑通。4.3 启动项目与常见启动报错速查环境准备完之后在项目根目录执行python app.py正常情况下终端会输出类似这样的提示* Running on http://127.0.0.1:5000然后用浏览器打开http://127.0.0.1:5000应该就能看到商城首页了。如果启动失败我整理了几个最常见的报错和解决思路报错信息原因解决方式ModuleNotFoundError: No module named flask依赖没有安装或者没有激活虚拟环境确认已激活虚拟环境执行pip install -r requirements.txtpymysql.err.OperationalError: (2003, Cant connect to MySQL server on 127.0.0.1)MySQL 服务没有启动启动 MySQL 服务Windows 下在“服务”里启动 mysqldmacOS/Linux 执行systemctl start mysql或service mysql startpymysql.err.OperationalError: (1045, Access denied for user rootlocalhost)数据库密码错误检查 config.py 里密码是否正确sqlalchemy.exc.ProgrammingError: (pymysql.err.ProgrammingError) (1049, Unknown database shop)数据库没有创建成功重新导入 sql/shop.sql确认 USE shop 语句执行成功ImportError: cannot import name db from app循环导入问题检查 models.py 和 app.py 中 db 的初始化位置确保 db 只在一个地方定义然后被引用jinja2.exceptions.TemplateNotFound: index.html模板目录路径不对确认 templates 文件夹和 app.py 在同一目录HTML 文件名和 render_template 参数一致我在第一次跑这套项目的时候卡在了一个非常隐蔽的问题上MySQL 8.x 默认端口是 3306 没错但我本机装了多个 MySQL 实例其中一个占用了 3307 端口config.py 里写的是 3306结果一直连不上。后来我用命令查了下端口占用情况才发现是端口冲突。遇到连接问题别只盯着密码端口和 host 也要检查一遍。5. 常见问题排查与避坑经验5.1 SQL 导入时报错的 3 个典型原因SQL 文件导入失败是最多人踩坑的环节。即使你完全照着 README 操作也可能因为环境差异报各种错误。我把 SQL 导入的问题分成三类第一类权限不足。如果你使用的 MySQL 账号不是 root或者 root 账号本身没有创建数据库的权限执行 CREATE DATABASE 时会报Access denied。这种情况最简单的处理方式是用 root 账号导入或者在 MySQL 里给当前账号授予对应权限GRANT ALL PRIVILEGES ON shop.* TO 你的用户名localhost; FLUSH PRIVILEGES;第二类字符集问题。脚本里如果用了SET NAMES utf8mb4而你的 MySQL 客户端默认字符集不是 utf8mb4导入过程中可能出现Incorrect string value错误。这种情况需要确认你的客户端连接字符集或者在建库语句里显式指定CREATE DATABASE shop CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;第三类版本兼容问题。MySQL 5.6 及以下版本对 utf8mb4 索引长度有限制建表时如果某个 varchar 字段设置了过长索引会报Specified key was too long。这种情况最简单的解决办法是升级 MySQL 版本或者修改表结构把索引字段改短。现在新装的 MySQL 基本都是 8.0 了碰到这个问题的概率不大但如果你用的是老服务器就要注意这一点。导入成功后强烈建议手动执行几条查询语句验证数据完整性比如看商品表有没有数据、用户表有没有管理员账号。这样可以确认脚本执行是否完整避免后续调试时才发现某张表是空的又要回头排查。5.2 页面 500 / 404 的排查思路项目跑起来之后访问页面时遇到 500 或 404是 Flask 学习过程中一定会碰到的情况。我分享一套排查思路可以让你快速定位问题。先看终端窗口的报错信息。Flask 默认开启 debug 模式时浏览器页面上会显示完整的异常堆栈终端里也会有 traceback。看到 traceback第一件事不是读最后一行而是要从下往上找你自己项目里的文件路径。比如 traceback 里出现File E:\project\views.py, line 42, in index这样的行说明问题出在 views.py 第 42 行再往上看具体是什么异常。404 的问题相对简单。它表示路径不存在可能的原因有三个一是 URL 拼写错误比如多写了一个斜杠二是视图函数没有注册正确的路由装饰器三是动态路由参数类型不匹配比如路由写的是int:product_id但访问的是字符串。在 base.html 的导航链接里如果url_for写错视图函数名也会导致 URL 生成错误最终访问到不存在的路径。500 的问题稍微复杂。它表示服务端代码执行出错常见的问题有模板里引用了不存在的变量、数据库查询返回 None 后继续调用了属性、Session 里没有某个 key 就直接读取。这些错误在单测或者调试模式下都很容易暴露但在生产环境关闭 debug 后用户只能看到空白的 500 页面所以开发阶段一定要保持 debugTrue方便定位问题。5.3 安全加固从 SQL 注入到密码管理的进阶建议虽然这是一个学习项目但我觉得有必要把“安全”这件事放到这么靠后的位置来讲因为很多新手会把注意力全放在功能实现上等真正部署到公网被攻击之后才后悔。这套源码里其实已经用 ORM 的参数化查询避免了很多注入风险因为 Flask-SQLAlchemy 在处理filter_by(usernameusername)这类查询时会自动对参数进行转义不会把输入内容当成 SQL 代码执行。但如果你在代码里发现了这样的写法那就要特别注意# 反例直接拼接 SQL 语句 sql SELECT * FROM user WHERE username %s % username result db.session.execute(sql)这种拼接字符串的方式就是典型的 SQL 注入漏洞。攻击者可以在用户名输入框里填 OR 11拼接出来的 SQL 就变成了WHERE username OR 11条件恒为真直接绕过密码验证。我之前在某开源项目里看到过这种写法当场惊出一身冷汗。建议你在阅读这套源码时全局搜索一下有没有直接调用db.session.execute且参数是字符串拼接的情况。如果看到了改成参数化查询# 正确做法参数化查询 result db.session.execute( text(SELECT * FROM user WHERE username :name), {name: username} )除了 SQL 注入还有一个容易忽视的安全点是debugTrue。Flask 的 debug 模式会开启 Werkzeug 调试器这个调试器在浏览器里提供一个交互式终端攻击者可以直接在页面上执行任意 Python 代码。如果你把这个项目部署到公网服务器时忘了关闭 debug那基本等于把服务器的 root 权限拱手送人。所以上线之前务必在 config.py 里把 debug 改成 False并且换一个复杂的 SECRET_KEY。关于密码管理前面已经讲了 Werekzeug 哈希存储的原理。我再补充一条实操建议如果你要重新初始化数据库初始的管理员密码是写在 SQL 里的哈希值你并不知道原始明文。这个时候不需要去破解 SQL只需要直接改数据库里的哈希值或者用代码里注册接口重新创建一个管理员账号再把 user 表的 role 字段改成 admin 就行。我在调试后台功能时经常这么干比去翻文档找初始密码快得多。6. 拿到源码之后我建议你按这个顺序改造一遍这部分算是我个人对这套源码最有价值的复盘因为在跑通整个项目的基础上我实际动手做的事情就是在这个源码上做二次开发也踩了很多坑。如果你已经把这个项目跑通了下一步不是急着在新项目里重复造轮子而是把改造这套源码当成一次更深入的学习。我的建议是从这几个方向入手方向一把“固定数据”改成“可配置数据”。项目的商品分类、轮播图、公告这类内容目前可能是静态写在代码或模板里的可以试着把它们放到数据库里做一个简单的分类管理表然后由后台页面动态维护。这一步能让你理解“配置数据”和“业务数据”的本质区别。方向二给用户模块加角色权限。目前用户和管理员是同一个表靠字段区分。你可以试着自己实现一个装饰器比如admin_required加到后台管理路由上让非管理员访问时自动跳转或返回 403。这个练习会让你对 Flask 装饰器有更深入的理解。方向三用 Flask 蓝图重构路由。现在的 views.py 里可能堆了所有路由你可以试着把它拆成 user_blueprint、product_blueprint、order_blueprint 三个模块分别放不同业务的路由。这个动作做完之后你会明显感受到项目结构清晰度的提升。方向四给 SQL 文件加上更新脚本。模拟一个真实场景上线后商品表需要增加一个“是否推荐”的字段。直接改原始建表语句会破坏已有用户的数据库正确做法是写一个ALTER TABLE的迁移脚本让老用户可以平滑升级。相信我等你真的维护一个在跑的项目时这个技能比会写十个增删改查都重要。如果你能按这个顺序把这套商城源码吃透你掌握的就不只是 Flask 的语法了而是一套完整的 Web 项目组织方法论。我当年也是从类似的项目开始慢慢拆、慢慢改才逐渐建立起自己对 Web 开发的整体认知。这个过程没有什么捷径唯一的建议就是多动手别光看不练。本文还有配套的精品资源点击获取
返回列表