Django用了五年,我用10天改成Go网站
2025年5月,我终于把用 Django 搭了 5 年的网站(经常优化+功能),重构成了 Go 项目,仅仅用了 10 天。这不是因为我有多厉害,而是因为 Gemini 和 ChatGPT 真的太强了,在重建过程中遇到很多奇怪问题,不一一列举了,只写重要的。
为什么要从 Django 换到 Go?
我的 Django 网站运行在一台 2 核 2G 8M 带宽的服务器上,越来越卡。有朋友打开网页要花二三十秒,有时候 CDN 在国内也加载不出来,模板继承一改就报错,页面功能多了之后越来越难维护,写文章有时候会500。
我曾经偶然发现:用render 后端Go 的网站,在一台 512M 内存、0.1 核 CPU 的服务器上都能跑得很流畅,内存只用了 几M 出头,比 Django 省太多了,只要用go可以不花钱了!
重构过程的崩溃与惊喜
为了保证迁移平滑进行,我在 Go 项目中保持了与原 Django 项目完全一致的数据库结构,并且前端模板和样式也做了最小化改动,确保网站外观基本保持不变,后端全部改。这样用户和后台管理都无需适应新的界面,体验无缝衔接。
代码结构好乱,强迫症爆炸
一开始看 Go 的项目结构,满屏的 struct
定义,逻辑都写在不同地方,看着就很焦虑。很多结构体一眼看上去都差不多,我总担心写重复了,而且 Go 没有缩进强制检查,格式一乱,心情也乱。
指针 & 报错满天飞
虽然我学 C++ 很多年,但指针这个东西我还是没搞太明白。Go 的 nil
报错经常让我措手不及。编译器老是提示“invalid memory address or nil pointer dereference”,让我一度怀疑自己是不是该干点别的。
但每次我想放弃时,都是 Gemini 和 ChatGPT 把我救回来。只要把报错一贴、逻辑一说,它们就能秒给解决方案,还能帮我一步一步调试。
评论功能最难搞
要说最折腾的功能,非评论系统莫属。
Django 里我用的是 GenericForeignKey
+ content_type
来实现“文章、友链都能评论”的逻辑。但 Go 里没有这个玩意,我只好自己写一个字段 comment_type
,自己处理评论的来源判断逻辑。
后台管理系统也没现成的 Django Admin,我就写了一个简陋的管理页面,功能不多,但能用。而且 为了安全起见,我加了每页管理员权限判断,虽然注册功能暂时还没写。
一些关键技术改进
- 模板改为 API 返回 JSON,再由前端渲染,避免 Django 模板继承时一改就崩的问题。
- 评论接口统一处理文章与友链评论,通过类型字段识别来源。
- 内存使用:Go ~20M(以后可以买更低配服务器了😁)
[root@server blog]# ps -p 3864229 -o pid,comm,%cpu,%mem
PID COMMAND %CPU %MEM
3864229 main 0.0 1.1
[root@server blog]# pmap -x 3864229 | grep total
total kB 1543276 20828 9628
- 性能测试https://pagespeed.web.dev/(使用 Go 后):
- FCP(首次内容绘制):0.8 秒
- LCP(最大内容绘制):1.3 秒
- TBT(总阻塞时间):170 毫秒
- CLS(布局偏移):0.005
总分:性能 83,SEO 83,无障碍 77,最佳实践 96
遇到的一些坑
- 菜单按钮点击无效? 原来是 CDN 加载失败了,国内访问
popper.js
卡得不行,建议尽量自托管或者用国内 CDN。
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
- GitLab 活动图表数据的插入坑点
模板中原本用 <script id="gitlab-activity-chart-data">
包含数据,结果浏览器无法读取 JSON,换成 <span style="display:none;">
就好了。
<span style="display: none;" id="gitlab-activity-chart-data" type="application/json">
{{.GitLabChartDataJSON}}
</span>
密码加密方式保持和 Django 一致
为了实现“用户不需要重新注册”,我保留了原有 Django 用户数据库,同时在 Go 端实现了与 Django 相同的密码校验逻辑,默认密码使用 PBKDF2(带 SHA256)进行加密。
评论 content_type_id和Django 一致
为了实现“评论显示出来”,我修改评论的数据库(改代码发现没作用,django 的content_type 不清楚怎么实现的,只有这样了🤣)。
UPDATE comments_comment
SET content_type_id = 2,
object_id = 0
WHERE content_type_id = 25
AND object_id = 1;
以后新增评论接口,需要go语言改 增加contentTypeMapNameToID 和对应模块结构体参数定义
comments\comments.go
// --- ContentType 名称与ID转换 (你需要根据你的系统实现或配置这个) ---
var contentTypeMapNameToID = map[string]int64{
"article": 1, // 示例: 假设 blog.Article 在 django_content_type 表中ID为1
"friendlink_page": 2, // 示例: 假设某个代表友链页的模型的ID为2
// ... 定义你所有可评论对象的类型名称到ID的映射 ...
}
friendlinks\handlers.go
var formOnError *comments.CommentFormData
commentSectionHTML, errRenderComment := comments.RenderCommentSectionForPage(r, commentCfg, formOnError)
if errRenderComment != nil {
log.Printf("FriendLinkController.PageHandler: Error rendering comment section: %v", errRenderComment)
// 提供一个用户友好的回退HTML
commentSectionHTML = template.HTML("<div class='alert alert-warning' role='alert'>评论区暂时无法加载,请稍后再试。</div>")
}
pageData := FriendLinksPageData{
CommentSectionHTML: commentSectionHTML,
CommentSubmitSuccess: r.URL.Query().Get("comment_success"), // 从URL query获取
CommentSubmitErrorGlobal: r.URL.Query().Get("comment_form_error"), // 从URL query获取
}
写在最后:感谢 AI
我不是专业的后端,也不是专业的前端。其实很多功能实现过程都是在 ChatGPT 和 Gemini 的“陪跑”下完成的。
我问的问题千奇百怪,比如:
- “Go 怎么判断字符串是不是空?”
- “我的 JSON 怎么解析失败了?”
- “评论接口设计有没有更优雅的方案?”
- “我的评论下的回复怎么没显示?”
而它们永远不烦、不累、不会嘲笑我,能给我示例代码、解释思路、还会提醒我注意安全问题。
接下来要做的事
- 补上用户注册和找回密码功能
- 完善评论管理 UI 和审核机制
- 提升前端加载速度,CDN 国内可用
- 增加缓存策略,避免 API 重复请求
- 逐步引入前端框架(考虑 HTMX / Alpine.js)
- 看看服务器稳定性会不会挂
无需 Django 的 Gunicorn:使用 Air 热重载运行
在 Go 项目中,不再依赖 Django 的 Gunicorn 或其他 WSGI 服务器。可以直接使用 Air 实现开发时的热重载,并在生产环境用如下命令后台运行(有更新时air短暂停服务器停几秒重启,supervisor不会挂但比较占内存,这五年间使用supervisor遇到各种问题所有没使用):
nohup air > air.log 2>&1 </dev/null & disown
air
:支持代码改动后自动重编译并重启服务,极大提升开发效率。nohup
+disown
:让进程脱离终端,即使关闭 SSH 会话也能继续运行。- 日志输出到
air.log
,方便排查问题。
这样就省去了额外的进程管理工具,启动简单、可热重载,适合很多中小型 Go 服务。
最后给一句建议
如果你正觉得 Django 跑不动了,不妨试试 Go。 如果你觉得 Go 太难了,不妨问问 ChatGPT 或 Gemini。
AI 真的是开发者最强的外挂工具。 感谢它们,帮我完成了曾经觉得不可能完成的工作。
本文作者: 永生
本文链接: https://yys.zone/detail/?id=423
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
评论列表 (0 条评论)