Golang GAE - 结构中的intID for mustache

时间:2012-03-31 13:37:07

标签: google-app-engine google-cloud-datastore go mustache

这是应用的Example。基本代码在:golang-code / handler / handler.go(主题应该出现一个ID!)

我试图在Google Appengine上的Golang中构建一个小博客系统,并使用Mustache作为模板引擎。

所以,我有一个结构:

type Blogposts struct {
    PostTitle   string
    PostPreview string
    Content     string
    Creator     string
    Date        time.Time
}

数据通过

传递给GAE
    datastore.Put(c, datastore.NewIncompleteKey(c, "Blogposts", nil), &blogposts)

因此,GAE自动分配一个intID(int64)。 现在我试图获得最新的博客

// Get the latest blogposts
c := appengine.NewContext(r)
q := datastore.NewQuery("Blogposts").Order("-Date").Limit(10)

var blogposts []Blogposts
_, err := q.GetAll(c, &blogposts)

直到所有事情都正常,但当我尝试访问intID(或stringID,无论如何)时,我无法访问: - (

<h3><a href="/blog/read/{{{intID}}}">{{{PostTitle}}}</a></h3>

(PostTitle有效,intID没有,我已经尝试了数千件事,没有用:-()

有人有想法吗?这太棒了!

编辑: 我用胡子。

http://mustache.github.com/

在我使用的代码中:

x["Blogposts"] = blogposts
data := mustache.RenderFile("templates/about.mustache", x)
sendData(w, data) // Equivalent to fmt.Fprintf

然后可以使用{{{Content}}}或{{{PostTitle}}}等在.mustache模板中访问数据。

4 个答案:

答案 0 :(得分:15)

正如hyperslug所指出的,实体的id字段在键上,而不是它被读入的结构。

另一种方法是在结构中添加一个id字段,并将数据存储区告诉ignore it,例如:

type Blogposts struct {
    PostTitle   string
    PostPreview string
    Content     string
    Creator     string
    Date        time.Time
    Id          int64 `datastore:"-"`
}

然后,您可以在调用GetAll()之后手动填充Id字段

keys, err := q.GetAll(c, &blogposts)
if err != nil {
    // handle the error
    return
}
for i, key := range keys {
    blogposts[i].Id = key.IntID()
}

这样做的好处是不会引入额外的类型。

答案 1 :(得分:7)

intID是Key的内部属性而不是struct,可以通过getter访问:

id := key.IntID()

GetAll会返回您未使用的[]*Key

_, err := q.GetAll(c, &blogposts)

解决此问题的一种方法是创建一个包含帖子和密钥信息的viewmodel结构(未经测试,但这是它的要点):

  //... handler code ...

  keys, err := q.GetAll(c, &blogposts)
  if err != nil {
    http.Error(w, "Problem fetching posts.", http.StatusInternalServerError)
    return
  }

  models := make([]BlogPostVM, len(blogposts))
  for i := 0; i < len(blogposts); i++ {
    models[i].Id = keys[i].IntID()
    models[i].Title = blogposts[i].Title
    models[i].Content = blogposts[i].Content
  }

  //... render with mustache ...
}

type BlogPostVM struct {
  Id int
  Title string
  Content string
}

答案 2 :(得分:2)

我知道这个问题已有几年了,但以下文章在这方面对我非常有帮助:Golang basics with Google Datastore

在文章中,作者提供了一个很好的示例,说明如何运行通过其ID获取实体的查询...

func GetCategory(c appengine.Context, id int64) (*Category, error) {
  var category Category
  category.Id = id

  k := category.key(c)
  err := datastore.Get(c, k, &category)
  if err != nil {
    return nil, err
  }

  category.Id = k.IntID()

  return &category, nil
}

...以及获取具有关联ID的实体列表/集合:

func GetCategories(c appengine.Context) ([]Category, error) {
  q := datastore.NewQuery("Category").Order("Name")

  var categories []Category
  keys, err := q.GetAll(c, &categories)
  if err != nil {
    return nil, err
  }

  // you'll see this a lot because instances
  // do not have this by default
  for i := 0; i < len(categories); i++ {
    categories[i].Id = keys[i].IntID()
  }

  return categories, nil
}

上面的代码段非常接近@koz的有用答案。

答案 3 :(得分:0)

AFAICS,Blogposts结构没有字段intID,但它有一个字段PostTitle。我想这可能是为什么前者没有,后者确实被渲染的原因,尽管我从未使用过胡子......