Beego本身不内置CMS功能,但凭借其MVC结构、ORM、bee工具链和模块化设计,可快速搭建轻量级CMS;需在models层定义Article等结构体并正确注册模型,用自定义路由实现后台路径,配合权限校验与HTML安全渲染。

beego 本身不内置“内容管理系统(CMS)”功能,但它的 MVC 结构、orm、bee 工具链和模块化设计,让快速搭建一个轻量级 CMS 成为现实。关键不是“有没有 CMS”,而是你能否在 models 层定义好 Article、Category、User,在 controllers 层写出符合权限逻辑的增删改查,再用 views 渲染出管理界面——这整套流程,beego 都已铺好路。
如何用 beego 快速搭起 CMS 的数据骨架
CMS 的核心是内容建模。别一上来就写后台页面,先在 models/article.go 定义结构体:
type Article struct {
Id int `orm:"auto"`
Title string `orm:"size(200)"`
Content string `orm:"type(text)"`
Category *Category `orm:"rel(fk)"`
Author *User `orm:"rel(fk)"`
CreatedAt time.Time `orm:"auto_now_add;type(datetime)"`
UpdatedAt time.Time `orm:"auto_now;type(datetime)"`
}
注意三点:
-
orm:"rel(fk)"表示外键关联,必须配合orm.RegisterModel(new(Article), new(Category), new(User))在初始化时注册全部模型,否则QueryTable("article").RelatedSel()会 panic -
auto_now_add和auto_now是beego orm特有行为,不依赖数据库默认值,也不支持 SQLite 的DEFAULT CURRENT_TIMESTAMP写法 - 字段名首字母大写才能被 ORM 识别——小写的
title不会映射到数据库列
为什么 bee generate model 生成的代码不能直接用
bee generate model article 确实能生成基础结构,但它默认只加 orm:"pk" 和 orm:"auto",其他字段全是 string 且无长度限制,直接用于生产环境容易触发 MySQL 的 sql_mode=STRICT_TRANS_TABLES 报错。
你需要手动补全:
- 时间字段必须显式声明
time.Time类型 +orm:"auto_now_add"等 tag - 文本类字段区分
size(255)(短文本)和type(text)(长内容),避免 ORM 自动生成TEXT导致索引失效 - 外键字段必须是
*OtherModel指针类型,不能是int;否则RelatedSel()查不到关联数据
后台路由和权限控制怎么绕过 beego 默认的 RESTful 路由
CMS 后台通常需要 /admin/article/create、/admin/article/123/edit 这类非标准路径,而 beego.Router("/article",&ArticleController{},"*:Article") 会强制走 Get()/Post() 方法映射,不灵活。
正确做法是关闭自动方法绑定,用自定义路由:
beego.Router("/admin/article", &ArticleController{}, "get:List;post:Create")
beego.Router("/admin/article/create", &ArticleController{}, "get:ShowCreateForm")
beego.Router("/admin/article/:id:int/edit", &ArticleController{}, "get:ShowEditForm;post:Update")
beego.Router("/admin/article/:id:int/delete", &ArticleController{}, "post:Delete")
这样每个 URL 明确对应一个方法,便于在 Prepare() 中统一做登录校验和权限检查,比如:
func (c *ArticleController) Prepare() {
if !c.IsLogin() {
c.Redirect("/login", 302)
return
}
if !c.HasPermission("article:edit") {
c.Abort("403")
return
}
}
模板里怎么安全渲染用户提交的 HTML 内容
CMS 的文章正文往往含 HTML 标签,但 {{.Content}} 会原样输出并执行脚本——这是 XSS 高危点。
beego 模板默认不转义,必须显式处理:
- 前端展示用
{{html .Content}},它调用 Go 的template.HTML类型转换,信任该字符串为安全 HTML - 但前提是后端入库前已做过净化(例如用
bluemonday库过滤 script、iframe 等标签),否则{{html}}只是“信任”,不等于“安全” - 编辑页回填时,用
{{.Content | safe}}(需在模板中注册safe函数)或更稳妥地用{{.Content | html}}防止双编码
最易忽略的一点:Beego 的 Render() 会自动对 .Data 中所有字段做 HTML 转义,除非你显式调用 c.Data["Content"] = template.HTML(rawHTML) ——很多人卡在这一步,以为模板语法错了,其实是后端没转类型。











