質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.06%

checkboxで投稿した情報をデータベースに登録して、表示させたい。

解決済

回答 2

投稿

  • 評価
  • クリップ 5
  • VIEW 2,493

score 806

前提・実現したいこと

Google App Engine(Python)で、質問サイト(teratailのようなもの)を作成しようとしています。
フレームワークとしてwebapp2、テンプレートエンジンとしてJinja2を利用しています。
質問を投稿する時に、(複数の)タグを選択して投稿してもらいたいのですが、
タグの選択がデータベースに反映されません。
質問タイトル、質問内容の投稿には成功しております。

発生している問題・エラーメッセージ

ソースコード

#以下、タグと質問のデータモデルを扱うクラス
class Tags(ndb.Model):
    id = ndb.IntegerProperty(indexed=True)
    name = ndb.StringProperty(indexed=False)

tags = Tags.query().order(Tags.id)

class Questions(ndb.Model):
    title = ndb.StringProperty(indexed = False)
    content = ndb.TextProperty(indexed = False)
    tag = ndb.KeyProperty(repeated=True,kind=Tags)

#以下、テンプレートエンジンにデータを送るためのクラス
class MainPage(webapp2.RequestHandler):
template_values = {
    'taglist':tags,
}
template = JINJA_ENVIRONMENT.get_template('index.html')
self.response.write(template.render(template_values))

#以下、質問投稿を扱うクラス
class Question(webapp2.RequestHandler):
    def post(self):
        question = Questions()
        question.title = self.request.get('title')
        tags = [Tags(key=t) for t in self.request.get_all('tag')]
        question.tag = [t.key for t in tags]
        question.content = self.request.get('content')
        question.put()


投稿画面のテンプレートは、下記のとおりです。
該当するチェックボックスをチェックして、質問タイトルと質問内容を入力して、投稿ボタンを押すというものです。

#以下、質問一覧
{% for question in questions %}
{{question.title}}<br>
{{question.content}}<br>
{% for tag in question.tag %}
{{tag.name}}   #ここに、各質問のタグを表示したい
{% endfor %}

#以下、投稿フォーム
<form method="post" action="/sign">
{% for tag in taglist %}
<input type="checkbox" name="tag" value={{tag.key.id()}}>{{tag.n    ame}}
{% endfor %}
<input name ="title" size=100% maxlength="130" type="text">
<textarea cols=100% name="content" rows="13"></textarea>
<button type="submit">submit</button>
</form>


上記のコードにより、投稿フォームのタグのチェックボックスには、下記のように表示されるようになっており、ここまでは私の狙いどおりです。
<input type="checkbox" name="tag" value=6351328917848064>タグA
<input type="checkbox" name="tag" value=4943954034294784>タグB
……

なお、タグは、事前に登録されています。

しかし、実際に投稿すると、
BadValueError: Expected Key, got u'6351328917848064'
というエラーが生じます。
htmlのテンプレートがおかしいのか、pythonの方がおかしいのか分かりません。
なお、タグに関する部分を削除した状態では、質問タイトルも質問内容もデータベースに登録され、htmlにも表示されますので、タグに関する扱いのみが間違っていると思います。

私としては、各質問のタグを表示させるところまでやりたいです。
しかし、現時点では、タグをデータベースに登録する時点でつまづいています。
どうしたらよいかお分かりの方、よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

tags = [Tags(key=t) for t in self.request.get_all('tag')]
        question.tag = [t.key for t in tags]


↑を↓にするとどうですか?

question.tag = [ndb.Key(Tags, t) for t in self.request.get_all('tag')]
訂正
question.tag = [ndb.Key(Tags, int(t)) for t in self.request.get_all('tag')]


テンプレートは

{{tag.get().name}}


で参照してください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/23 21:53

    上記の件、下記の質問を投稿しました。
    https://teratail.com/questions/23263

    キャンセル

  • 2015/12/24 17:59

    すみません、回答を間違えてました。
    訂正します。

    キャンセル

  • 2015/12/24 19:41

    いえ、いつもご回答頂き、ありがとうございます。

    キャンセル

-1

webapp2というフレームワークにはあまり詳しく無いのですが、
エラーの内容は、

class Tags(ndb.Model):
    id = ndb.IntegerProperty(indexed=True)


のところでidにIntegerを期待しているにも関わらず

tags = [Tags(key=t) for t in self.request.get_all('tag')]


のところでtの値がunicode(u'6351328917848064')なので型が合わない(BadValueError)と言われているよう見受けられます。

例えば、

tags = [Tags(key=int(t)) for t in self.request.get_all('tag')]


のようにtをintに型変換したら上手くいったりしないでしょうか?

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/22 21:47

    ご回答いただき、ありがとうございました。
    ご指摘の方法では、
    BadValueError: Expected Key, got 6245775801581568
    のようなエラーが出てしまいました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.06%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る