Kayで登録済みのReferencePropertyの値を初期値としたコンボボックスを表示する

Kayで登録済みのReferencePropertyの値を初期値としたコンボボックスを表示する
ために、KayのFormのinitialをどういうふうに書くのかを説明したいと思いますが、

form = フォーム名(initial={"フォームクラスの中での変数名": オブジェクト名.key()})


うまく一言で表せないので、例で示します。


RDBで以下2つのテーブルのフィールドとレコードがあります。
?Categories

id category
001 novel
002 dictionary
003 cartoon


?Books - category_idフィールドはCategoriesテーブルへの外部キー

id book category_id
1 羅生門 001
2 ワンピース 002
3 広辞苑 002


この保存済みの「ワンピース」のカテゴリーを決定するためのcategory_idを変更するページでは、現在登録されているCategoriesテーブルの002:dictionaryを初期値として残る001: novelと003を表示するコンボボックスをたいてい作ると思います。


HTMLだとこんな感じです。

<select name="book">
  <option value="001">novel</option>
  <option value="002" selected>dictionary</option>
  <option value="003">cartoon</option>
</select>


これと同じことをKayのformでやるには、というのが、今回の記事です。
まずはModelを定義します。
?Categories

class Categories(db.Model):
  id = db.StringProperty()
  category = db.StringProperty()

  def __unicode__(self):
    return self.category

?Books

class Books(db.Model):
  id = db.StringProperty()
  book = db.StringProperty()
  category = db.ReferenceProperty(Categories)
  # RDBとは異なり、categoryにはCategoriesオブジェクトを入れるのでidという名前を省きます。


次に、BooksクラスのFormを定義します。

class BooksForm(forms.Form):
  form_id = forms.TextField(label="Book ID")
  form_book = forms.TextField(label="Book Name")
  form_category = forms.ModelField(model=Categories, default=None, label="Category of Book")


RDB例のフィールドとレコードに当たるデータを作ってdatastoreに保存します。
(view.pyの書き方は割愛します)

# Save Categories objects
c1 = Categories()
c1.id = "001"
c1.category = "novel"
c1.put()

c2 = Categories()
c2.id = "002"
c2.category = "dictionary"
c2.put()

c3 = Categories()
c3.id = "003"
c3.category = "cartoon"
c3.put()

# Save Books objects
b1 = Books()
b1.id = "1"
b1.book = u"羅生門"
b1.categry = c1
b1.put()

b2 = Books()
b2.id = "2"
b2.book = u"ワンピース"
b2.category = c2
b2.put()

b3 = Books()
b3.id = "3"
b3.book = u"広辞苑"
b3.category = c2
b3.put()


初期データが登録できたところで、ワンピースのカテゴリーを変更します。
例として、b2のkey(自動発番)は200とします。
表示してほしいHTMLのイメージはこんな感じで。

<form action="" method="post">
<p>ID: <input type="text" name="id" value="1" /><p>
<p>Book: <input type="text name="book" value="ワンピース" /></p>
<p>Category:
 <select name="category">
 <option value="1">Novel</option>
 <option value="2" selected="selected">Dictionary</option>
 <option value="3">Cartoon</option>
 </select>
</p>
<input type="hidden" name="key" value="200" />
<input type="submit" value="submit">
</form>


このようなHTMLソースをKayのFormで吐かせるには、
まず、大元のBooksクラスを取り出します。
(今回はkeyをGETデータとして受け取るものとします)

book_query = Books.get_by_id(int(request.values.get('key')))

次に、Bookのフォームを以下のように呼び出せば、登録済みのModelPropertyの値を初期としたコンボボックスを作るFormができます。

book_form = BookForm(initial={"form_category": book_query.category.key())

詳しく説明しようとしたら逆に解りづらくなってしまっていると思うので、誰か解りやすく解説するためのいい方法があったら指摘してもらえるとありがたいです。