Golang GAE - intID in struct for mustache

 ̄綄美尐妖づ 提交于 2019-12-03 14:11:17

intID is an internal property of a Key not the struct, and is accessible through a getter:

id := key.IntID()

GetAll returns []*Key, which you're not using:

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

One way to get around this is to create a viewmodel struct that has both your post and key info (untested, but this is the gist of it):

  //... 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
}

As hyperslug pointed out, the id field of an entity is on the key, not the struct it gets read into.

Another way around this is to add an id field to your struct and tell datastore to ignore it, eg:

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

You can then populate the Id field manually after a call to GetAll() like so

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

This has the benefit of not introducing an extra type.

I know this question is a couple years old, but the following article was very helpful to me in this regard: Golang basics with Google Datastore.

In the article, the author provides a nice example of how you can run a query that gets an entity by its 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
}

...as well as getting a list/collection of entities with their associated 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
}

The snippet above is very close to the helpful answer by @koz.

AFAICS, the Blogposts struct has no field intID, but it has a field PostTitle. I guess that could be the reason why the former doesn't and the later does get rendered, though I've never used Mustache...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!