記錄下beego 多對(duì)多模型查詢的吐血經(jīng)歷

最近寫一個(gè)博客練手,文章功能需要增加一個(gè)標(biāo)簽的功能,一篇文章可以有多個(gè)標(biāo)簽,一個(gè)標(biāo)簽可以被多個(gè)文章使用,于是就想用m2m模型實(shí)現(xiàn),過程如下

文章模型簡(jiǎn)化如下:

type Article struct {

    Id          int       `form:"-"`
    //這個(gè)是標(biāo)簽
    Label       []*Label  `orm:"rel(m2m);rel_through(blog/models.Articlelabel)"`

}

這里說一下這個(gè)rel_through, 官方文檔的說法是pkg.models.struct 用點(diǎn)兒連接,但是實(shí)際情況不是路徑還是要用/ 不知道是不是我對(duì)官方文檔理解有問題,還是官方的說法有瑕疵

下面是標(biāo)簽?zāi)P停?/p>

type Label struct {
    Id int `form:"-"`
    Title string `form:"title"`
    //這個(gè)是文章關(guān)聯(lián)
    Article []*Article `orm:"reverse(many)"`
}

下面是關(guān)聯(lián)模型

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

注意關(guān)聯(lián)模型中的 ArticleLabel 都不能加id 查詢會(huì)自動(dòng)加上

我的列表查詢?nèi)缦?/p>

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
    }
        //這個(gè)是正確的寫法
    /*for k,_ := range list {
        o.LoadRelated(&list[k], "Label")
            
    }*/
      
        //這個(gè)是錯(cuò)誤的寫法
        for _, v := range list {
        o.LoadRelated(v, "Label")       
    }

    return list, nil
}

然后就報(bào)錯(cuò)了

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 <Ormer> cannot use non-ptr model struct `blog/models.Article`
...

Article 結(jié)構(gòu)體空指針,于是我查閱了文檔,發(fā)現(xiàn) LoadRelated參數(shù)都是指針, 下面是文檔給的例子

// 載入相應(yīng)的 Tags
post := Post{Id: 1}
err := o.Read(&post)
num, err := o.LoadRelated(&post, "Tags")

于是我把我的代碼也換成了指針o.LoadRelated(&v, "Label"),發(fā)現(xiàn)不報(bào)錯(cuò)了,但是也沒有查詢到。這就奇怪了。于是我想到是不是&v 并不是真的指向了原來的結(jié)構(gòu)體,經(jīng)過谷歌之后發(fā)現(xiàn)還真是這樣,for循環(huán)的時(shí)候 &v指向的其實(shí)是 v的地址,而不像PHP一樣就是原來的參數(shù)引用。那就只能用 list[k]來更改了
于是

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

這樣就成了,對(duì)于查詢一條記錄同理,只不過不需要循環(huán)我的list, 而是直接像官方文檔給的例子那樣寫就可以了

事后我測(cè)試

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

看來我還是基礎(chǔ)不過關(guān)啊,共勉

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Django 準(zhǔn)備 “虛擬環(huán)境為什么需要虛擬環(huán)境:到目前位置,我們所有的第三方包安裝都是直接通過 pip inst...
    33jubi閱讀 1,390評(píng)論 0 5
  • 來自網(wǎng)絡(luò) 序言 目前形勢(shì),參加到iOS隊(duì)伍的人是越來越多,甚至已經(jīng)到供過于求了。今年,找過工作人可能會(huì)更深刻地體會(huì)...
    用心在飛閱讀 920評(píng)論 5 4
  • 轉(zhuǎn)盤玄學(xué):??1、抽獎(jiǎng)之前要洗洗手,也俗稱把手中的晦氣洗掉,用一雙純凈的雙手抽獎(jiǎng),一個(gè)不小心說不準(zhǔn)就抽中了哦!??...
    Sep_D_Dai閱讀 458評(píng)論 6 4
  • 以前我國(guó)沒有今天這樣的鐘表,古代計(jì)時(shí)的工具叫“銅殼滴漏”。它是靠銅壺里的水,一滴一滴往下漏來計(jì)算時(shí)間的長(zhǎng)短的。它的...
    簡(jiǎn)什么閱讀 321評(píng)論 0 3
  • P97-P100 1.按小鬧鐘:用生活中常見的物品來訓(xùn)練寶寶的聽力。 2.媽媽要隨時(shí)變換藏鬧鐘的方式和地點(diǎn),并且注...
    蒲公英_2018閱讀 377評(píng)論 0 1

友情鏈接更多精彩內(nèi)容