必须调用c.Set("user", &u)将绑定后的结构体传入模板上下文,否则r.HTML()会清空表单;结构体字段需带form:"name"标签,模板用{{.user.Name}}和{{.FormErrors.name}}渲染数据与错误。

Buffalo 表单提交后验证失败,数据会清空——这不是模板写错了,而是上下文没传过去。必须手动把绑定后的结构体塞进 c,否则 r.HTML() 渲染时根本看不到用户刚输的内容。
表单验证失败后怎么保留用户输入
直接调用 r.HTML("new.html") 会让所有输入框变空,因为原始 POST 数据只在 request body 里活一次,c.Bind() 读完就没了,模板里又没拿到结构体实例。
- 先用
c.Bind(&u)把请求体映射到结构体(比如User) - 紧接着调用
c.Set("user", &u),让模板能通过{{.user.Name}}取值 - 结构体字段必须带
form:"name"tag,否则Bind不知道该往哪填 - 模板里用
{{.FormErrors.name}}显示字段级错误,{{if .FormErrors}}判断整体是否有错
为什么 validate.Validate(&u) 通过了,数据库却报错
validate 包只做内存校验,不查数据库。邮箱重复、用户名已存在这类问题,它完全感知不到。
Buffalo框架 1.0.1 版本源码包下载,适合需要错误处理改进、依赖更新、render.Download 注释和 request logger 调整的 v1 项目。
- 常见错误信息是
ERROR: duplicate key value violates unique constraint "users_email_key" - 解决办法是在
validate.Validate(&u)后加一层 DB 查询:比如tx.Where("email = ?", u.Email).First(&existing) - 或者捕获
pop.Create返回的pop.Error,用strings.Contains(err.Error(), "duplicate")做判断 - 别指望
validate覆盖所有业务规则——它只是第一道过滤网
模板字段拼错或结构体缺字段,怎么提前发现
Buffalo 不检查模板里写的 {{.user.Phone}} 对应的结构体有没有 Phone 字段,直到运行时渲染才 panic。
- 在
app.go的App()函数里加上app.PrecompileTemplates() - 启动
buffalo dev时就会扫描所有templates/下的文件,提前报出类似template: "users/new.html":12:7: unknown field "phone" in struct - 这个检查只对
.HTML()生效,.JSON()或自定义响应不会触发 - 配合 IDE 的字段补全和
go vet,能避开大部分低级拼写错误
真正容易被忽略的是:结构体字段的 form tag 和模板中引用的键名必须严格一致,大小写、下划线都不能差——Buffalo 不做任何 normalize,错一个字符,Bind 就静默跳过,用户输入就丢了。

















