Golang GAE - intID в структуре для усов - PullRequest
6 голосов
/ 31 марта 2012

Вот пример приложения.Необходимый код находится в: golang-code / handler / handler.go (После того, как у субъекта должен появиться идентификатор!)

Я пытаюсь создать небольшую систему блогов в Golang на Google Appengine и использовать 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 нет, я пробовал тысячи вещей, ничего не работает :-()

У кого-нибудь есть идеи? Это было бы здорово!

Редактировать: Iиспользовать усы.

http://mustache.github.com/

В коде, который я использую:

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

И затем к данным можно получить доступ в шаблоне .mustache с помощью {{{Content}}} или {{{PostTitle}}} и т. д.

Ответы [ 4 ]

15 голосов
/ 02 октября 2012

Как указал HyperSlug, поле id объекта находится в ключе, а не в структуре, в которую оно читается.

Другим способом решения этой проблемы является добавление поля id в вашу структуру и указание хранилищу данных для игнорировать его , например:

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

После этого вы можете заполнить поле Id вручную после вызова GetAll (), например,

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

Преимущество заключается в том, что вы не вводите дополнительный тип.

7 голосов
/ 01 апреля 2012

intID является внутренним свойством Key, а не структурой, и доступно через геттер:

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 голосов
/ 06 декабря 2015

Я знаю, что этому вопросу пару лет, но следующая статья мне очень помогла в этом отношении: Основы Голанга с Google Datastore .

В статье авторапредоставляет хороший пример того, как вы можете выполнить запрос, который получает сущность по ее идентификатору ...

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
}

Фрагмент выше очень близок к полезному ответу @ koz.

0 голосов
/ 31 марта 2012

AFAICS, структура Blogposts не имеет поля intID, но имеет поле PostTitle.Я полагаю, что это может быть причиной того, что первый не делает, а последний рендерит, хотя я никогда не использовал усы ...

...