记录下beego 多对多模型查询的吐血经历

最近写一个博客练手,文章功能需要增加一个标签的功能,一篇文章可以有多个标签,一个标签可以被多个文章使用,于是就想用m2m模型实现,过程如下

文章模型简化如下:

type Article struct {

    Id          int       `form:"-"`
    //这个是标签
    Label       []*Label  `orm:"rel(m2m);rel_through(blog/models.Articlelabel)"`

}

这里说一下这个rel_through, 官方文档的说法是pkg.models.struct 用点儿连接,但是实际情况不是路径还是要用/ 不知道是不是我对官方文档理解有问题,还是官方的说法有瑕疵

下面是标签模型:

type Label struct {
    Id int `form:"-"`
    Title string `form:"title"`
    //这个是文章关联
    Article []*Article `orm:"reverse(many)"`
}

下面是关联模型

type Articlelabel struct {
    Id int 
    Article *Article `orm:"rel(fk)"`
    Label *Label `orm:"rel(fk)"`
}

注意关联模型中的 ArticleLabel 都不能加id 查询会自动加上

我的列表查询如下

func ArtList() ([]Article, error) {
    var list []Article

    o := orm.NewOrm()
    orm.Debug = true
    _, err := o.QueryTable("article").RelatedSel().Limit(10).All(&list)
    if err != nil {
        return []Article{}, err
    }
        //这个是正确的写法
    /*for k,_ := range list {
        o.LoadRelated(&list[k], "Label")
            
    }*/
      
        //这个是错误的写法
        for _, v := range list {
        o.LoadRelated(v, "Label")       
    }

    return list, nil
}

然后就报错了

2020/03/01 18:54:29.795 [C] [panic.go:679]  the request url is  /admin/article
2020/03/01 18:54:29.795 [C] [panic.go:679]  Handler crashed with error  cannot use non-ptr model struct `blog/models.Article`
...

Article 结构体空指针,于是我查阅了文档,发现 LoadRelated参数都是指针, 下面是文档给的例子

// 载入相应的 Tags
post := Post{Id: 1}
err := o.Read(&post)
num, err := o.LoadRelated(&post, "Tags")

于是我把我的代码也换成了指针o.LoadRelated(&v, "Label"),发现不报错了,但是也没有查询到。这就奇怪了。于是我想到是不是&v 并不是真的指向了原来的结构体,经过谷歌之后发现还真是这样,for循环的时候 &v指向的其实是 v的地址,而不像PHP一样就是原来的参数引用。那就只能用 list[k]来更改了
于是

for k,_ := range list {
        o.LoadRelated(&list[k], "Label")
            
    }

这样就成了,对于查询一条记录同理,只不过不需要循环我的list, 而是直接像官方文档给的例子那样写就可以了

事后我测试

a := [] int {1}
    for k,v := range a {
        fmt.Println(&v)
        fmt.Println(&a[k])
    }
//两个不同的地址
//0x40e024
//0x40e020

看来我还是基础不过关啊,共勉

你可能感兴趣的:(记录下beego 多对多模型查询的吐血经历)