【没事学点啥】TurboBlog轻量级个人博客项目——Turbo Blog 项目学习与上线指南

Turbo Blog 项目学习与上线指南

整理日期:2026-05-06

项目定位:一个轻量个人博客。Django 像发动机,负责数据、接口、登录、评论、上传、RSS 和 sitemap;原生 HTML/CSS/JS 像驾驶舱,负责页面、写作后台和交互。

效果如图所示:

1. 项目总览表

模块 作用 关键文件 你需要记住的一句话
前端入口 浏览器打开的第一张纸 index.html 只挂载 #app,再加载 config.jsscript.js
前端配置 决定 API 请求打到哪里 config.js 同域部署时留空;前后端分开时填后端公网地址。
前端逻辑 页面渲染、路由、写作、评论、AI 问答 script.js 所有前端"大脑"都在这里。
前端样式 颜色、布局、响应式、卡片、表单 styles.css 页面长相基本都改这里。
站点图片 头像、上传图、分享图 assets/ 固定头像在根图片,后台上传图在 assets/uploads/
Django 配置 环境变量、数据库、上传目录、AI 配置 turboblog/settings.py 项目的总电闸。
Django 路由 URL 到函数的分发 turboblog/urls.py 看到接口地址,先来这里找对应函数。
数据模型 数据库表结构 blog/models.py 文章、评论、用户、会话、验证码都在这里定义。
业务接口 API、RSS、sitemap、静态页面服务 blog/views.py 后端主战场,绝大多数行为都在这里。
跨域处理 CORS 和 OPTIONS blog/middleware.py 允许前端跨域调用后端。
初始化数据 从旧 JSON 导入站点与文章 blog/management/commands/seed_initial_data.py 空库第一次启动时喂一点内容。
默认数据库 SQLite 数据文件 backend/data/turbo-blog-django.sqlite 本地真实数据在这里。
旧数据种子 初始文章、站点信息 backend/data/db.json 只影响首次导入或重建库。
启动脚本 Windows 本地启动/停止 start-blog.batstop-blog.bat 双击即可本地跑起来。
部署配置 云平台启动命令 Procfile Heroku/Railway 类平台会读它。
测试脚本 后端冒烟检查 scripts/test_django_backend.py 改完后跑它,像出门前检查钥匙。

当前本地数据库概况:站点名 Turbo Blog,公网地址仍是 http://localhost:5173,共有 4 篇文章,4 篇已发布文章,1 条评论,0 条待审评论。

2. 架构图

浏览器
index.html
config.js
script.js
/api/... 请求
turboblog/urls.py
blog/views.py
blog/models.py
backend/data/turbo-blog-django.sqlite
assets/uploads/
RSS / sitemap / robots
可选 AI 模型 API

这不是 React/Vue 项目,而是"原生前端 + Django 单体后端"。浏览器加载静态文件,script.jsfetch() 调 Django API;Django 再读写 SQLite,必要时保存上传图片。

3. 要改内容时去哪里

你想改什么 去哪个文件 具体位置/关键词
浏览器标题、SEO 描述、分享图 index.html <title>meta name="description"og:*
API 后端地址 config.js window.TURBO_BLOG_CONFIG.apiBase
首页大标题和介绍文案 script.js hero()
顶部导航、底部版权 script.js layout()
AI 小助手区域文案 script.js aiAssistantPanel()
首页文章列表、筛选、短札、关于 script.js renderHome()
文章详情页 script.js renderPost()
写作后台表单 script.js renderEditor()
管理员登录弹窗 script.js adminLoginModal()
前端按钮点击、提交表单、上传图片 script.js bindEvents()
前端 Markdown 渲染规则 script.js markdownToHtml()renderInlineMarkdown()
颜色、字体、间距、移动端布局 styles.css :root、对应 class、@media
头像/站点图标 assets/avatar-blue-anime.png 替换同名图片最省事
上传图片存储位置 assets/uploads/ 后台上传后自动写入
API 路由增删 turboblog/urls.py urlpatterns
文章字段、评论字段、用户字段 blog/models.py PostCommentBlogUser 等模型
文章增删改查逻辑 blog/views.py posts()post_detail()
评论提交和审核逻辑 blog/views.py post_comments()admin_comments()admin_comment_detail()
验证码、限流、敏感词 blog/views.pyturboblog/settings.py captcha()is_rate_limited()SENSITIVE_WORDS
图片上传大小和格式 blog/views.pyturboblog/settings.py upload_image()IMAGE_UPLOAD_LIMIT
AI 检索和 RAG 逻辑 blog/views.pyturboblog/settings.py ai_ask()best_post_passages()call_rag_model()
SQLite 文件位置 turboblog/settings.py SQLITE_FILE
生产环境密钥、域名、Debug turboblog/settings.py 环境变量读取区
初始文章内容 backend/data/db.json 只在空库导入时生效
初始化导入规则 blog/management/commands/seed_initial_data.py handle()
本地启动逻辑 start-blog.bat 端口、迁移、启动命令
停止本地服务 stop-blog.bat 端口 4000,5173,8000
云平台启动命令 Procfile web: 后面的命令

manage.py 的作用:它是 Django 的"控制开关"。你运行这些命令时都靠它找到项目配置:

python manage.py runserver python manage.py migrate python manage.py

check python manage.py seed_initial_data

它里面最关键的一行是:

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "turboblog.settings")

意思是:告诉 Django,配置文件在 turboblog/settings.py。

注意:站点标题、描述、公网地址已经存进 SQLite 后,改 backend/data/db.json 不会自动覆盖旧库。已有库要改 public_url,可用:

bash 复制代码
python manage.py shell -c "from blog.models import SiteSetting; s=SiteSetting.objects.get(pk=1); s.public_url='https://你的域名'; s.save()"

4. 数据模型速记

模型 数据库里的角色 关键字段
SiteSetting 站点设置 titledescriptionpublic_url
BlogUser 管理员/作者账号 usernamepassword_hashrole
Session 登录会话 token_hashexpires_atrevoked_at
Post 博客文章 titleslugexcerptcontenttagsstatus
Comment 评论 postauthorcontentapprovedstatus
Captcha 评论验证码 answer_hashexpires_atusedfailures
RateLimit 评论频率限制 keycountexpires_at

最重要的关系:一篇 Post 可以有多条 Comment;评论默认 pending,管理员通过后才公开展示。

5. API 地图

接口 方法 用途 是否需要管理员
/api/health GET 健康检查
/api/storage GET 查看存储状态
/api/site GET 获取站点信息
/api/posts GET 文章列表、搜索 否;带草稿需登录
/api/posts POST 新建文章
/api/posts/<slug或id> GET 文章详情 否;草稿需登录
/api/posts/<slug或id> PUT/DELETE 修改/删除文章
/api/posts/<slug或id>/comments POST 提交评论
/api/captcha GET 获取评论验证码
/api/admin/comments GET 待审/已审评论列表
/api/admin/comments/<id> PUT/DELETE 审核或删除评论
/api/uploads POST 上传图片
/api/auth/login POST 管理员登录
/api/auth/me GET 检查登录状态
/api/auth/logout POST 退出登录 是/有 token 更完整
/api/ai/ask POST 博客知识问答
/sitemap.xml GET 搜索引擎站点地图
/rss.xml GET RSS 订阅
/robots.txt GET 爬虫规则

6. 核心流程

6.1 打开首页

浏览器访问 /,Django 的 frontend() 返回 index.htmlscript.jsloadSite(),再 navigate(),最后 loadPosts() 拉文章并 renderHome() 画出首页。

6.2 写文章

点击"写作"后,前端先调用 /api/auth/me 检查管理员。登录通过后进入 renderEditor();保存时提交到 /api/posts/api/posts/<id>,Django 写入 Post 表。

6.3 评论

文章详情页先拉 /api/captcha。访客提交评论时,后端检查验证码、敏感词和频率限制;评论进入 pending,管理员在写作后台通过后才展示。

6.4 图片上传

写作后台选择图片,前端转成 base64 发到 /api/uploads;后端校验格式和大小,然后写入 assets/uploads/,返回 Markdown 图片地址。

6.5 AI 问答

问题进入 /api/ai/ask。后端把问题分词,在已发布文章里找相关片段;没有 AI_API_KEY 时用本地检索回答,有 key 时把片段交给 DeepSeek/OpenAI-compatible 模型生成回答。

7. 本地开发命令

Windows 推荐:

bat 复制代码
start-blog.bat

手动启动:

bash 复制代码
python -m pip install -r requirements.txt
python manage.py migrate --noinput
python manage.py seed_initial_data
python manage.py runserver [::]:5173

检查:

bash 复制代码
python manage.py check
python scripts/test_django_backend.py

本地地址:

txt 复制代码
http://localhost:5173
http://localhost:5173/api/health
http://localhost:5173/sitemap.xml

本地默认管理员令牌/密码:dev-token。上线必须改。

8. 生产环境变量

变量 生产建议 作用
DJANGO_SECRET_KEY 必填,长随机字符串 Django 加密密钥
DJANGO_DEBUG 0 关闭调试模式
ALLOWED_HOSTS 你的域名,www.你的域名 允许访问的域名
ADMIN_TOKEN 强随机令牌 后台令牌登录
ADMIN_PASSWORD 强密码 管理员用户名密码登录
SQLITE_FILE 持久磁盘路径 SQLite 数据库位置
JSON_BODY_LIMIT 默认即可 JSON 请求体大小
IMAGE_UPLOAD_LIMIT 默认 5MB 上传图片大小
SENSITIVE_WORDS 按需加词 评论敏感词
AI_PROVIDER local/deepseek/openai AI 提供方
AI_API_KEY 有模型才填 模型 API Key
AI_MODEL deepseek-chat 模型名称

9. Turbo Blog Django 公网发布指南

当前项目已经切换为 Django 后端:一个 Python 服务同时提供前端页面、博客 API、图片上传、RSS、sitemap 和 robots.txt。

整体发布流程如下:

  1. 把项目推送到 GitHub。
  2. 连接 GitHub 仓库。
  3. 在 Railway里新建 Web Project和Volume。

部署平台 + 持久磁盘 Volume + SQLite

部署成功如图所示:

9.1Railway部署

Railway 是什么

Railway 是一个"云上自动机房"。你不用买服务器、装 Nginx、配 HTTPS,它会从 GitHub 拉代码,自动构建,运行你的 Django,并给你一个公网网址。

你的链路会变成:

GitHub 仓库

-> Railway 自动拉代码

-> 安装 requirements.txt

-> 执行启动命令

-> Gunicorn 跑 Django

-> Railway 给公网域名和 HTTPS

Volume 是什么

Volume 不是"音量",是"持久硬盘"。

普通 Railway 容器像临时酒店房间:你可以在里面写文件,但重新部署/重启后,房间可能被打扫干净。

Volume 像你租的储物柜:挂到服务里以后,文件会长期保留。

你的博客长期写文章,最重要的是数据库不能丢,所以要让 SQLite 住进 Volume:

/app/data/turbo-blog-django.sqlite

Railway 官方说明:Volumes 用来给服务保存持久数据,挂载路径会变成服务里可读写的目录;Volume 在服务启动时挂载,不在 build/pre-deploy 阶段挂载。参考:

bash 复制代码
python manage.py migrate --noinput && python manage.py seed_initial_data && gunicorn turboblog.wsgi:application --bind 0.0.0.0:$PORT

项目也带了 Procfile,支持会读取 Procfile 的平台自动部署。

9.2新建项目

New Project

-> Deploy from GitHub repo

-> 选择你的博客仓库

Railway 会生成一个项目,里面会有一个服务。这个服务就是你的 Django 博客容器

9.3设置启动命令

进入你的服务:

Service

-> Settings

-> Deploy

-> Start Command

bash 复制代码
python manage.py migrate --noinput && python manage.py seed_initial_data && gunicorn turboblog.wsgi:application --bind 0.0.0.0:$PORT

9.4必填环境变量

操作如下图所示:

之后直接复制下方代码:

text 复制代码
DJANGO_DEBUG=0
DJANGO_SECRET_KEY=一串很长的随机字符
ADMIN_TOKEN=你的后台强令牌
ADMIN_PASSWORD=你的后台强密码
ALLOWED_HOSTS=*
SQLITE_FILE=/app/data/turbo-blog-django.sqlite
UPLOAD_DIR=/app/data/uploads

密钥可以本地生成:

bash 复制代码
python -c "import secrets; print(secrets.token_urlsafe(50))"

9.5Volume 创建

先ctrl+k

然后在这个搜索框里输入 volume

接下来一直点

最后Mount Path: /app/data

结束

9.6访问

1、开全局才能访问的到网站

2、如图所示,这才是你个人的网站

10. 上线前检查清单

检查项 目标
DJANGO_DEBUG=0 不暴露调试信息
DJANGO_SECRET_KEY 已更换 不用本地默认密钥
ADMIN_TOKEN/ADMIN_PASSWORD 已更换 不用 dev-token
ALLOWED_HOSTS 是真实域名 不长期使用 *
SQLITE_FILE 在持久磁盘 重启/重建不丢文章
assets/uploads/ 可持久保存 上传图片不丢
已备份 SQLite 至少定期备份数据库文件
SiteSetting.public_url 是 HTTPS 域名 sitemap/RSS 链接正确
/sitemap.xml 可访问 搜索引擎可发现文章
/robots.txt 可访问 爬虫规则正常
页脚有 ICP/公安备案号 国内长期运行需要
评论审核开启 访客评论不直接公开
python scripts/test_django_backend.py 通过 核心接口没坏

11. 快速学习路线

按这个顺序学,像从地图边缘走到城市中心:

  1. 先跑起来:用 start-blog.bat 打开 http://localhost:5173,写一篇测试文章。
  2. 看入口:读 index.html,知道页面如何加载 JS/CSS。
  3. 看前端状态:读 script.js 顶部的 state,它就是页面记忆。
  4. 看请求封装:读 apiBase()request()apiHeaders(),理解前端怎样带 token 调接口。
  5. 看页面渲染:读 renderHome()renderPost()renderEditor(),它们把数据变 HTML。
  6. 看事件系统:读 bindEvents(),所有点击、输入、提交都在这里被接住。
  7. 看路由:读 navigate(),理解 //post/.../editor/... 怎么切页面。
  8. 看 Django 路由:读 turboblog/urls.py,把 API 地址和视图函数连起来。
  9. 看业务接口:读 blog/views.py,重点看文章、评论、上传、AI 四组函数。
  10. 看数据表:读 blog/models.py,再对照 API 返回的数据。
  11. 看配置:读 turboblog/settings.py,把环境变量、SQLite、上传目录、AI 配置看懂。
  12. 看测试:读 scripts/test_django_backend.py,它是项目"应该怎样工作"的简版说明书。

练手建议:

练习 修改文件 收获
把首页标题改成自己的话 script.jshero() 熟悉渲染函数
改主题色 styles.css:root 熟悉样式变量
新增一个文章标签筛选 script.jscategoryOf()renderHome() 熟悉前端状态和筛选
给文章加字段 blog/models.py、迁移、blog/views.pyscript.js 走完整前后端链路
改 AI 提示词 blog/views.pyrag_messages() 理解 RAG 边界
加一个新 API turboblog/urls.py + blog/views.py 理解 Django 路由
相关推荐
Slow菜鸟1 小时前
Docker 学习篇(三)| Docker安装指南(Linux版)
linux·学习·docker
Tutankaaa1 小时前
知识竞赛软件SaaS版 vs 本地部署
人工智能·经验分享·笔记·学习
L-影1 小时前
常见的 ORM 工具
开发语言·数据库·fastapi·orm
小仙女的小稀罕2 小时前
培训要点写不完不会整理?规范培训转待办可这样操作
大数据·人工智能·学习·自然语言处理·语音识别
飞Link2 小时前
构筑你的数字第二大脑:Obsidian 深度解析与配置指南
开发语言·python
JaydenAI2 小时前
[Deep Agents:LangChain的Agent Harness-02]构建抽象的文件系统
python·langchain·ai编程·ai agent·deep agents·harness
2403_883261092 小时前
如何用 nodeType 与 nodeName 准确判断当前节点的物理类型
jvm·数据库·python
qq_413502022 小时前
如何利用 Block Tree 避免不必要的子组件重渲染?Vue3 编译黑科技
jvm·数据库·python
m0_624578592 小时前
CSS定位如何实现多行文字垂直居中_通过绝对定位模拟表格
jvm·数据库·python