这个项目是我大学时期边学习边完成的一个练手项目。最开始做它的目的很简单:我想通过一个完整的小型 Web 应用,把课堂上学到的 Python、数据库、前端页面和后端路由真正串起来,而不是只停留在单独写脚本或完成作业的阶段。

项目的主题是“镜头社交平台”。它以热门相机镜头数据为核心,围绕镜头排行榜、镜头详情、数据可视化、用户登录注册、个人主页和评论评价等功能,做了一个偏社区化的信息展示平台。

项目仓库地址:lens-social-platform →

项目简介

Lens Social Platform 是一个基于 Flask 的镜头排行榜与评价平台。用户可以浏览热门镜头排行,查看镜头的详细参数,也可以登录后发布评论和评分。项目还加入了数据看板,用图表展示镜头价格、焦段、卡口类型、画幅分类等信息。

虽然这是一个练手项目,但它基本覆盖了一个 Web 应用的常见组成部分:用户注册、登录、登出,Session 登录状态管理,镜头排行榜展示,镜头详情页,评论与评分功能,用户主页和个人投稿列表,数据可视化图表,数据表格页,以及数据库初始化与本地运行支持。

后来我还基于这个项目做了一个日语版分支,对 UI、README 和页面内容进行了日语化,并补充了“AI 翻译,不一定准确”的提示。

项目实现截图

下面是项目整理和修复后的主要页面截图,覆盖排行榜、数据看板、表格、详情页、登录注册和用户相关页面。

镜头社交平台首页排行榜截图
首页排行榜:热门镜头列表与左侧数据概览。
镜头社交平台数据图表页截图
数据看板:使用 ECharts 展示镜头数据分布。
镜头社交平台数据表格页截图
数据表格页:以表格方式浏览镜头参数。
镜头详情页截图
镜头详情页:展示规格参数、图片和评论入口。
镜头社交平台登录页截图
登录页:用户登录入口。
镜头社交平台注册页截图
注册页:新用户创建账号。
镜头社交平台用户主页截图
用户主页:展示用户资料与个人信息。
镜头社交平台用户评论列表截图
用户评论列表:查看用户发布过的评论。

技术选型

这个项目的后端使用 Flask。选择 Flask 的原因是它比较轻量,适合学习 Web 开发的基本流程。相比一开始就使用大型框架,Flask 可以让我更清楚地理解路由、模板、请求、响应、Session 和数据库之间的关系。

  • Python / Flask / Flask-SQLAlchemy
  • SQLAlchemy ORM
  • SQLite / MySQL
  • Jinja2 模板
  • HTML / CSS / JavaScript
  • Bootstrap 风格 UI
  • ECharts 与 ECharts WordCloud

数据库方面,项目最初使用 MySQL。但在本地运行时,如果 MySQL 没有启动,就会出现连接失败的问题。后来我为项目增加了 SQLite 本地 fallback:如果没有配置 DATABASE_URL,项目会自动使用本地 SQLite,并在首次启动时根据 lens.sql 初始化数据。这样项目在新环境中更容易跑起来。

项目结构

项目整体结构比较传统,适合初学 Flask 时理解分层:

.
├── app.py                 # Flask 应用入口
├── config.py              # 配置文件
├── db_init.py             # 数据库初始化
├── models.py              # 数据模型
├── lens.sql               # 初始数据
├── requirements.txt       # 依赖
├── blueprints/
│   ├── auth.py            # 登录注册
│   ├── lens.py            # 镜头详情、图表、表格、评论
│   └── users.py           # 用户主页、资料、投稿
├── templates/             # 页面模板
└── static/                # 静态资源

我在项目里使用了 Blueprint 来拆分不同业务模块。虽然当时项目规模不算大,但这个拆分让我第一次比较直观地理解了“模块化后端结构”的意义:认证逻辑、用户逻辑、镜头逻辑分别放在不同文件里,后续维护会清晰很多。

核心功能实现

镜头排行榜

首页展示热门镜头 TOP50,包括镜头图片、型号、价格、人气度和评分。用户可以通过排行榜进入镜头详情页。这个页面的重点不只是展示数据,还包括搜索和简单的数据概览。左侧嵌入了几个 ECharts 图表,右侧是主要排行列表,整体类似产品报价网站和数据看板的结合。

镜头详情页

详情页展示某个镜头的完整信息,包括镜头图片、型号、参考价格、镜头分类、镜头画幅、卡口、焦距范围、最近对焦距离、最大光圈、滤镜尺寸和镜头重量。详情页下方还显示用户评论。如果用户未登录,页面会提示先登录;如果用户已经登录,则可以发布评分和评论。

用户系统

项目实现了基础的用户注册、登录和登出功能。登录状态通过 Flask Session 保存。用户可以访问自己的主页,修改简介,也可以查看自己发布过的评论。从现在的角度看,这套用户系统还比较简单,例如密码仍然是明文保存,这并不适合真实生产环境。但作为大学时期的练手项目,它帮助我理解了认证流程的基本结构。

评论与评分

评论功能是项目里比较接近“社交平台”概念的部分。用户可以针对某个镜头提交评论和评分,评论会关联到用户和镜头,并在对应页面展示。通过这个功能,我开始理解数据库表之间的关系:用户、镜头、评论并不是孤立存在的,而是需要通过字段进行关联。

数据可视化

项目中我使用 ECharts 做了多个图表,包括镜头卡口类型统计、镜头焦段统计、价格分布箱线图、滤镜尺寸与最大光圈统计、画幅与分类占比、热门关键词词云。

做这部分时,我遇到过一个典型的前端问题:饼图的图例会遮挡图表本体。后来通过调整图表容器高度、图例位置、饼图中心点和半径,把图例移动到图表下方,解决了视觉重叠问题。这让我意识到,数据可视化不仅仅是“把图画出来”,还需要考虑不同屏幕尺寸下的可读性和布局稳定性。

遇到的问题和修复

MySQL 连接失败

最早项目默认连接本地 MySQL。如果用户没有启动 MySQL,打开页面会直接报错:

OperationalError: Can't connect to MySQL server on 'localhost'

这个问题后来通过引入 SQLite fallback 解决。现在项目默认可以直接使用 SQLite 运行,降低了启动门槛。

前端显示 undefined

在日语版改造过程中,我把页面表头翻译成了日语,但前端 JS 里读取数据时也误用了日语字段名。然而数据文件里的内部字段名仍然是中文,例如 排名型号价格。结果页面渲染时找不到字段,就显示成了 undefined

这个问题的修复方式是:页面显示文本可以翻译,但数据字段 key 必须保持和数据源一致。最终我保留了日语 UI,同时让 JS 继续读取原始内部字段名。这个 bug 给我的教训很直接:展示层语言和数据结构字段不能混为一谈。国际化时,最好有明确的字段映射或 i18n 字典,而不是直接修改业务字段名。

日语版分支

后来我为项目创建了一个日语版分支 japanese-version,主要包含 UI 文案日语化、README 日语化、页面截图补充、AI 翻译提示、表格页 undefined 修复、详情页排行 undefined 修复、饼图图例遮挡修复。

分支地址:japanese-version →

项目收获

这个项目并不是一个成熟的商业项目,但它对我来说很重要。因为它让我第一次比较完整地经历了一个 Web 项目的开发过程:如何设计页面路由,如何组织 Flask 项目结构,如何使用 ORM 操作数据库,如何把 SQL 数据渲染到页面,如何处理用户登录状态,如何做评论和评分功能,如何使用 ECharts 做数据可视化,如何排查前后端字段不一致的问题,以及如何把项目整理成 GitHub 仓库和分支。

更重要的是,它让我意识到:练手项目的价值不在于一开始写得多完美,而在于它能暴露真实问题。数据库连不上、页面 undefined、图表遮挡、截图不完整、README 不清楚,这些问题都很琐碎,但它们恰恰是完整项目中一定会遇到的工程细节。

后续可以优化的方向

  • 密码改为哈希存储
  • 增加表单校验和错误提示
  • 优化数据库表设计
  • 将前端字段映射抽离成统一配置
  • 增加分页、评论编辑和删除功能
  • 将图表数据改为后端 API 动态生成
  • 增加自动化测试并改善 UI 一致性

总结

这个镜头社交平台是我大学时期边学边做的练手项目。它不复杂,也不完美,但它把后端、数据库、模板、前端交互、数据可视化和 GitHub 项目管理串到了一起。

对我来说,它最大的意义不是“做出了一个镜头网站”,而是通过一个具体主题,把零散的技术点变成了一个能运行、能展示、能继续维护的完整项目。这样的练习经历,也让我对 Web 开发有了更真实的理解。