beego在定义model时不支持slice类型属性,那么如何定义多对多关系映射??

weixin_38064966 2019-09-20 10:27:00
按照beego官网例子写的代码 :
```
type User struct {
Id int
Name string
Profile string
Post []*Post `orm:reverse(many)` //设置一对多的反向关系
}

type Post struct {
Id int
Title string
User *User `orm:rel(pk)` //设置一对多关系
Tags string
}
```
在main中运行程序,初始的时候会报错,如下:

```
field: models.User.Post, unsupport field type [], may be miss setting tag
```

跟了一下源码,错误是在models_utils.go中,getFieldType函数内报的。

```
if ft&IsFieldType == 0 {
err = fmt.Errorf("unsupport field type %s, may be miss setting tag", val)
}
```
完整代码 :

```go
func getFieldType(val reflect.Value) (ft int, err error) {
switch val.Type() {
case reflect.TypeOf(new(int8)):
ft = TypeBitField
case reflect.TypeOf(new(int16)):
ft = TypeSmallIntegerField
case reflect.TypeOf(new(int32)),
reflect.TypeOf(new(int)):
ft = TypeIntegerField
case reflect.TypeOf(new(int64)):
ft = TypeBigIntegerField
case reflect.TypeOf(new(uint8)):
ft = TypePositiveBitField
case reflect.TypeOf(new(uint16)):
ft = TypePositiveSmallIntegerField
case reflect.TypeOf(new(uint32)),
reflect.TypeOf(new(uint)):
ft = TypePositiveIntegerField
case reflect.TypeOf(new(uint64)):
ft = TypePositiveBigIntegerField
case reflect.TypeOf(new(float32)),
reflect.TypeOf(new(float64)):
ft = TypeFloatField
case reflect.TypeOf(new(bool)):
ft = TypeBooleanField
case reflect.TypeOf(new(string)):
ft = TypeVarCharField
case reflect.TypeOf(new(time.Time)):
ft = TypeDateTimeField
default:
elm := reflect.Indirect(val)
fmt.Println("ele.kind:", elm.Kind())
switch elm.Kind() {
case reflect.Int8:
ft = TypeBitField
case reflect.Int16:
ft = TypeSmallIntegerField
//case reflect.Slice: //自己测试填加
// ft = RelReverseMany
case reflect.Int32, reflect.Int:
ft = TypeIntegerField
case reflect.Int64:
ft = TypeBigIntegerField
case reflect.Uint8:
ft = TypePositiveBitField
case reflect.Uint16:
ft = TypePositiveSmallIntegerField
case reflect.Uint32, reflect.Uint:
ft = TypePositiveIntegerField
case reflect.Uint64:
ft = TypePositiveBigIntegerField
case reflect.Float32, reflect.Float64:
ft = TypeFloatField
case reflect.Bool:
ft = TypeBooleanField
case reflect.String:
ft = TypeVarCharField
default:
if elm.Interface() == nil {
panic(fmt.Errorf("%s is nil pointer, may be miss setting tag", val))
}
switch elm.Interface().(type) {
case sql.NullInt64:
ft = TypeBigIntegerField
case sql.NullFloat64:
ft = TypeFloatField
case sql.NullBool:
ft = TypeBooleanField
case sql.NullString:
ft = TypeVarCharField
case time.Time:
ft = TypeDateTimeField
}
}
}
if ft&IsFieldType == 0 {
err = fmt.Errorf("unsupport field type %s, may be miss setting tag", val)
}
```
从完整代码看,没有匹配slice这种类型,所以ft是零,导致报错。于是自己在新加了一个case ,上面代码中注释的两行,添加完后会报零值panic。

```
panic: reflect: call of reflect.Value.Interface on zero Value
```

官网给的例子,以及从网上查阅的资料都是这么写的,可以运行通过, 但是根据源码看确实不支持slice类型。所以如何想要做多对多的关系映射,使用beego框架该如何处理。

请指教,谢谢。

...全文
150 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_38065217 2019-09-20
  • 打赏
  • 举报
回复
一对多关系不应该是外键fk么 type Post struct { Id int Title string User *User `orm:rel(fk)` //设置一对多关系 Tags string } 多对多关系: type Post struct { Id int Title string User *User `orm:rel(m2m)` //设置一对多关系 Tags string }
weixin_38077891 2019-09-20
  • 打赏
  • 举报
回复
最开始写的fk,也不行。而且代码还没有走到检验一对多还是多对多,在检验类型的时候就报错了。
weixin_38081906 2019-09-20
  • 打赏
  • 举报
回复
细看了下,少了个双引号,应该是这样:Post []*Post `orm:"reverse(many)"`
weixin_38097166 2019-09-20
  • 打赏
  • 举报
回复
还有这个也少了双引号User *User `orm:"rel(pk)"` //设置一对多关系
weixin_38098817 2019-09-20
  • 打赏
  • 举报
回复
最后解决了吗?

435

社区成员

发帖
与我相关
我的任务
社区描述
其他技术讨论专区
其他 技术论坛(原bbs)
社区管理员
  • 其他技术讨论专区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧