Commit 8b9d6eee authored by astaxie's avatar astaxie Committed by GitHub

Merge pull request #2132 from Zaaksam/master

beego.ParseForm() improvement
parents c697b980 11ef5929
...@@ -280,15 +280,8 @@ func AssetsCSS(src string) template.HTML { ...@@ -280,15 +280,8 @@ func AssetsCSS(src string) template.HTML {
} }
// ParseForm will parse form values to struct via tag. // ParseForm will parse form values to struct via tag.
func ParseForm(form url.Values, obj interface{}) error { // Support for anonymous struct.
objT := reflect.TypeOf(obj) func parseFormToStruct(form url.Values, objT reflect.Type, objV reflect.Value) error {
objV := reflect.ValueOf(obj)
if !isStructPtr(objT) {
return fmt.Errorf("%v must be a struct pointer", obj)
}
objT = objT.Elem()
objV = objV.Elem()
for i := 0; i < objT.NumField(); i++ { for i := 0; i < objT.NumField(); i++ {
fieldV := objV.Field(i) fieldV := objV.Field(i)
if !fieldV.CanSet() { if !fieldV.CanSet() {
...@@ -296,6 +289,14 @@ func ParseForm(form url.Values, obj interface{}) error { ...@@ -296,6 +289,14 @@ func ParseForm(form url.Values, obj interface{}) error {
} }
fieldT := objT.Field(i) fieldT := objT.Field(i)
if fieldT.Anonymous && fieldT.Type.Kind() == reflect.Struct {
err := parseFormToStruct(form, fieldT.Type, fieldV)
if err != nil {
return err
}
continue
}
tags := strings.Split(fieldT.Tag.Get("form"), ",") tags := strings.Split(fieldT.Tag.Get("form"), ",")
var tag string var tag string
if len(tags) == 0 || len(tags[0]) == 0 { if len(tags) == 0 || len(tags[0]) == 0 {
...@@ -384,6 +385,19 @@ func ParseForm(form url.Values, obj interface{}) error { ...@@ -384,6 +385,19 @@ func ParseForm(form url.Values, obj interface{}) error {
return nil return nil
} }
// ParseForm will parse form values to struct via tag.
func ParseForm(form url.Values, obj interface{}) error {
objT := reflect.TypeOf(obj)
objV := reflect.ValueOf(obj)
if !isStructPtr(objT) {
return fmt.Errorf("%v must be a struct pointer", obj)
}
objT = objT.Elem()
objV = objV.Elem()
return parseFormToStruct(form, objT, objV)
}
var sliceOfInts = reflect.TypeOf([]int(nil)) var sliceOfInts = reflect.TypeOf([]int(nil))
var sliceOfStrings = reflect.TypeOf([]string(nil)) var sliceOfStrings = reflect.TypeOf([]string(nil))
......
...@@ -110,6 +110,17 @@ func TestHtmlunquote(t *testing.T) { ...@@ -110,6 +110,17 @@ func TestHtmlunquote(t *testing.T) {
} }
func TestParseForm(t *testing.T) { func TestParseForm(t *testing.T) {
type ExtendInfo struct {
Hobby string `form:"hobby"`
Memo string
}
type OtherInfo struct {
Organization string `form:"organization"`
Title string `form:"title"`
ExtendInfo
}
type user struct { type user struct {
ID int `form:"-"` ID int `form:"-"`
tag string `form:"tag"` tag string `form:"tag"`
...@@ -119,6 +130,7 @@ func TestParseForm(t *testing.T) { ...@@ -119,6 +130,7 @@ func TestParseForm(t *testing.T) {
Intro string `form:",textarea"` Intro string `form:",textarea"`
StrBool bool `form:"strbool"` StrBool bool `form:"strbool"`
Date time.Time `form:"date,2006-01-02"` Date time.Time `form:"date,2006-01-02"`
OtherInfo
} }
u := user{} u := user{}
...@@ -132,6 +144,10 @@ func TestParseForm(t *testing.T) { ...@@ -132,6 +144,10 @@ func TestParseForm(t *testing.T) {
"Intro": []string{"I am an engineer!"}, "Intro": []string{"I am an engineer!"},
"strbool": []string{"yes"}, "strbool": []string{"yes"},
"date": []string{"2014-11-12"}, "date": []string{"2014-11-12"},
"organization": []string{"beego"},
"title": []string{"CXO"},
"hobby": []string{"Basketball"},
"memo": []string{"nothing"},
} }
if err := ParseForm(form, u); err == nil { if err := ParseForm(form, u); err == nil {
t.Fatal("nothing will be changed") t.Fatal("nothing will be changed")
...@@ -164,6 +180,18 @@ func TestParseForm(t *testing.T) { ...@@ -164,6 +180,18 @@ func TestParseForm(t *testing.T) {
if y != 2014 || m.String() != "November" || d != 12 { if y != 2014 || m.String() != "November" || d != 12 {
t.Errorf("Date should equal `2014-11-12`, but got `%v`", u.Date.String()) t.Errorf("Date should equal `2014-11-12`, but got `%v`", u.Date.String())
} }
if u.Organization != "beego" {
t.Errorf("Organization should equal `beego`, but got `%v`", u.Organization)
}
if u.Title != "CXO" {
t.Errorf("Title should equal `CXO`, but got `%v`", u.Title)
}
if u.Hobby != "Basketball" {
t.Errorf("Hobby should equal `Basketball`, but got `%v`", u.Hobby)
}
if len(u.Memo) != 0 {
t.Errorf("Memo's length should equal 0 but got %v", len(u.Memo))
}
} }
func TestRenderForm(t *testing.T) { func TestRenderForm(t *testing.T) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment