首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >戈朗模板中引用对象的访问属性(Google应用程序引擎)

戈朗模板中引用对象的访问属性(Google应用程序引擎)
EN

Stack Overflow用户
提问于 2016-04-03 11:18:34
回答 1查看 203关注 0票数 1

我有一个数据模型Sections:

代码语言:javascript
运行
复制
type Sections struct{
    SectionName     string
    IsFather        bool
    ParentSection   *datastore.Key
}

我将部分作为值传递给golang模板,并且我希望获得ParentSection名称ParentSection.SectionName,所以如何从python{{ParentSection.get().SectionName}}中的jinja2这样的模板中实现这一点?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-04 08:08:57

html/template包不具有“应用引擎感知”,它不了解GAE平台,也不支持对此类引用的自动解析。

根据设计理念,模板不应包含复杂的逻辑。如果某些东西(或看起来)在模板中太复杂,则应该在函数中实现。您可以使用Template.Funcs()方法注册您的自定义函数,您可以从模板中调用该方法。

对于用例,我推荐以下自定义函数,它通过键加载Sections

代码语言:javascript
运行
复制
func loadSections(ctx appengine.Context, k *datastore.Key) (*Sections, error) {
    s := Sections{}
    err := datastore.Get(ctx, k, &s)
    return &s, err
}

请注意,您需要从数据存储加载实体的Context,因此您必须使它在模板参数中也可用。因此,您的模板参数可能如下所示:

代码语言:javascript
运行
复制
ctx := appengine.NewContext(r)

m := map[string]interface{}{
    "Sections": s, // A previously loaded Sections
    "Ctx":      ctx,
}

通过注册和使用该函数,您可以获得所需的内容:

代码语言:javascript
运行
复制
    t := template.Must(template.New("").Funcs(template.FuncMap{
        "loadSections": loadSections,
    }).Parse(`my section name: {{.Sections.SectionName}},
parent section name: {{(loadSections .Ctx .Sections.ParentSection).SectionName}}`))

    t.Execute(w, m)

现在假设您有一个名为Sections的父"parSecName",还有一个名为"childSecName"的子Sections,子ParentSection指向父SectionsSections。执行上面的模板,您将看到以下结果:

代码语言:javascript
运行
复制
my section name: childSecName,
parent section name: parSecName

完整示例

请参阅此完整的工作示例。注:仅为演示目的,不适合生产。

它注册/put路径以插入2 Sections。您可以使用任何其他路径来执行模板。所以,像这样测试它:

先插入2 Sections

代码语言:javascript
运行
复制
http://localhost:8080/put

然后执行并查看模板结果:

代码语言:javascript
运行
复制
http://localhost:8080/view

完整的可运行代码:

代码语言:javascript
运行
复制
// +build appengine

package gplay

import (
    "appengine"
    "appengine/datastore"
    "html/template"
    "net/http"
)

func init() {
    http.HandleFunc("/put", puthandler)
    http.HandleFunc("/", myhandler)
}

func myhandler(w http.ResponseWriter, r *http.Request) {
    ctx := appengine.NewContext(r)

    s := Sections{}
    if err := datastore.Get(ctx, datastore.NewKey(ctx, "Sections", "", 2, nil), &s); err != nil {
        panic(err)
    }

    m := map[string]interface{}{
        "Sections": s,
        "Ctx":      ctx,
    }

        t := template.Must(template.New("").Funcs(template.FuncMap{
            "loadSections": loadSections,
        }).Parse(`my section name: {{.Sections.SectionName}},
    parent section name: {{(loadSections .Ctx .Sections.ParentSection).SectionName}}`))

        t.Execute(w, m)
}

    func loadSections(ctx appengine.Context, k *datastore.Key) (*Sections, error) {
        s := Sections{}
        err := datastore.Get(ctx, k, &s)
        return &s, err
    }

func puthandler(w http.ResponseWriter, r *http.Request) {
    ctx := appengine.NewContext(r)

    s := Sections{"parSecName", false, nil}

    var k *datastore.Key
    var err error
    if k, err = datastore.Put(ctx, datastore.NewKey(ctx, "Sections", "", 1, nil), &s); err != nil {
        panic(err)
    }
    s.SectionName = "childSecName"
    s.ParentSection = k
    if _, err = datastore.Put(ctx, datastore.NewKey(ctx, "Sections", "", 2, nil), &s); err != nil {
        panic(err)
    }
}

type Sections struct {
    SectionName   string
    IsFather      bool
    ParentSection *datastore.Key
}

一些笔记

这个子父关系可以用Key本身建模,因为一个键可以有选择地包含父Key

如果您不想在实体的密钥本身中“存储”父密钥,也可以只存储密钥的名称或密钥的ID (取决于您使用的内容),因为可以构造密钥。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36384759

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档