Google app engine Golang GAE-小胡子的内部结构

Google app engine Golang GAE-小胡子的内部结构,google-app-engine,google-cloud-datastore,go,mustache,Google App Engine,Google Cloud Datastore,Go,Mustache,下面是该应用程序的一个示例。基本代码位于:golang code/handler/handler.go(主题后面应该显示一个ID!) 我试图在谷歌Appengine上在Golang建立一个小博客系统,并使用Mustache作为模板引擎 因此,我有一个结构: type Blogposts struct { PostTitle string PostPreview string Content string Creator string D

下面是该应用程序的一个示例。基本代码位于:golang code/handler/handler.go(主题后面应该显示一个ID!)

我试图在谷歌Appengine上在Golang建立一个小博客系统,并使用Mustache作为模板引擎

因此,我有一个结构:

type Blogposts struct {
    PostTitle   string
    PostPreview string
    Content     string
    Creator     string
    Date        time.Time
}
数据通过

    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,无论什么)时,我无法访问以下内容:-(


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

AFAICS,
Blogposts
结构没有字段
intID
,但它有一个字段
PostTitle
。我想这可能就是为什么前者没有,而后者得到渲染的原因,尽管我从未使用过Mustache…

intID
是键的内部属性,而不是结构,可以通过粗糙的吸气剂:

id := key.IntID()
返回未使用的
[]*键

_, err := q.GetAll(c, &blogposts)
解决此问题的一种方法是创建一个viewmodel结构,其中包含帖子和关键信息(未测试,但这是其要点):

/…处理程序代码。。。
key,err:=q.GetAll(c和blogposts)
如果错误!=零{
http.Error(w,“获取帖子的问题”,http.StatusInternalServerError)
返回
}
模型:=make([]BlogPostVM,len(blogposts))
对于i:=0;i
正如hyperslug所指出的,实体的id字段位于键上,而不是读取到的结构

另一种解决方法是向结构中添加一个id字段,并告诉数据存储,例如:

然后可以在调用GetAll()后手动填充Id字段,如下所示


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

我知道这个问题已经有好几年了,但下面的文章在这方面对我很有帮助:

在本文中,作者提供了一个很好的示例,说明如何运行一个查询,通过其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
}
func GetCategories(c appengine.Context)([]类别,错误){
q:=datastore.NewQuery(“类别”).Order(“名称”)
var类别[]类别
key,err:=q.GetAll(c和categories)
如果错误!=零{
返回零,错误
}
//你会经常看到这一点,因为
//默认情况下没有此选项
对于i:=0;i

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

{{{}}
:您是否正在扩展html/模板?如果是,请至少添加一段代码来查看。嗨,不,我使用胡子。请参见编辑:-)这与此无关。数据存储忽略“intID”和“stringID”:-((尝试通过NewIncompleteKey指定intID,它不起作用;-)我说的是行
数据:=mustache.RenderFile(“templates/about.mustache”,x)
,而不是数据存储。
RenderFile
函数应该如何知道
intID
?感谢您的回复。对不起,我的英语不好。(也许我听起来很粗鲁,但这不是我的本意!)x包含Blogposts结构(以及其他一些结构)。如果我尝试将intID添加到Blogposts结构中,这将不起作用,因为在数据库结构中不可能使用intID或类似的东西:-(稍等,我将编写一个小示例应用程序:-)(可能更容易帮助:-)-基本代码位于:golang code/handler/handler.goThank非常感谢,这对我帮助很大:-)
  //... 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
}
type Blogposts struct {
    PostTitle   string
    PostPreview string
    Content     string
    Creator     string
    Date        time.Time
    Id          int64 `datastore:"-"`
}
keys, err := q.GetAll(c, &blogposts)
if err != nil {
    // handle the error
    return
}
for i, key := range keys {
    blogposts[i].Id = key.IntID()
}
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
}
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
}