Golang GAE – 结构体中的intID用于mustache

huangapple go评论73阅读模式
英文:

Golang GAE - intID in struct for mustache

问题

这是一个应用程序的示例。关键代码在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)。
现在我尝试获取最新的博客文章

// 获取最新的博客文章
c := appengine.NewContext(r)
q := datastore.NewQuery("Blogposts").Order("-Date").Limit(10)

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

到目前为止,一切都正常,但是当我尝试访问intID(或stringID,无论哪个)时,我无法访问它 Golang GAE – 结构体中的intID用于mustache

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

(PostTitle可以工作,但intID不行,我尝试了很多方法,都没有成功 :-()

有人有想法吗?这将非常棒!

编辑:
我使用mustache。

http://mustache.github.com/

在代码中,我使用:

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

然后可以在.mustache模板中通过{{{Content}}}或{{{PostTitle}}}等方式访问数据。

英文:

Here is an Example of the app. The essential code is in: golang-code/handler/handler.go (After the subject should appear an ID!)

Im trying to build a little blog system in Golang on Google Appengine and use Mustache as template engine.

So, i have a struct:

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

The data is passed to GAE via

    datastore.Put(c, datastore.NewIncompleteKey(c, &quot;Blogposts&quot;, nil), &amp;blogposts)

So, GAE assigns automatically a intID (int64).
Now I tried to get the latest blogposts

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

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

Until there all things works fine, but when I try to access intID (or stringID, whatever) I dont have access to this Golang GAE – 结构体中的intID用于mustache

&lt;h3&gt;&lt;a href=&quot;/blog/read/{{{intID}}}&quot;&gt;{{{PostTitle}}}&lt;/a&gt;&lt;/h3&gt;

(PostTitle works, intID not, i've tried thousand of things, nothing worked Golang GAE – 结构体中的intID用于mustache )

Anyone an idea? This would be great!

Edit:
I use mustache.

http://mustache.github.com/

In the code I use:

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

And then the data can be accessed in the .mustache template with {{{Content}}} or {{{PostTitle}}} etc.

答案1

得分: 15

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

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

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 {
    // 处理错误
    return
}
for i, key := range keys {
    blogposts[i].Id = key.IntID()
}

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

英文:

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:&quot;-&quot;`
}

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

keys, err := q.GetAll(c, &amp;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.

答案2

得分: 7

intID是Key的一个内部属性,而不是结构体,可以通过getter方法访问:

id := key.IntID()

GetAll返回[]*Key,你没有使用它:

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

解决这个问题的一种方法是创建一个视图模型结构体,其中包含您的帖子和键信息(未经测试,但这是要点):

  //... 处理程序代码 ...

  keys, err := q.GetAll(c, &blogposts)
  if err != nil {
    http.Error(w, "获取帖子时出现问题。", 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
  }

  //... 使用mustache渲染 ...
}

type BlogPostVM struct {
  Id int
  Title string
  Content string
}
英文:

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, &amp;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, &amp;blogposts)
  if err != nil {
    http.Error(w, &quot;Problem fetching posts.&quot;, http.StatusInternalServerError)
    return
  }

  models := make([]BlogPostVM, len(blogposts))
  for i := 0; i &lt; 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
}

答案3

得分: 2

我知道这个问题已经有几年了,但是下面的文章对我在这方面非常有帮助:使用Google Datastore的Golang基础知识

在这篇文章中,作者提供了一个很好的例子,展示了如何通过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, &amp;category)
  if err != nil {
    return nil, err
  }

  category.Id = k.IntID()

  return &amp;category, nil
}

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

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

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

  // 你会经常看到这个,因为实例默认没有这个
  for i := 0; i &lt; len(categories); i++ {
    categories[i].Id = keys[i].IntID()
  }

  return categories, nil
}

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

英文:

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, &amp;category)
  if err != nil {
    return nil, err
  }

  category.Id = k.IntID()

  return &amp;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(&quot;Category&quot;).Order(&quot;Name&quot;)

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

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

  return categories, nil
}

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

答案4

得分: 0

AFAICS,Blogposts结构体没有intID字段,但它有一个PostTitle字段。我猜这可能是前者没有被渲染而后者被渲染的原因,尽管我从未使用过Mustache...

英文:

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

huangapple
  • 本文由 发表于 2012年3月31日 21:37:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/9956342.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定