djangoforms を使う

Google App Engine で開発。第六弾。

GAE python27 + django 1.3 です。GAE に含まれている django を使っています。

(追記 2012.9.5:djangoforms は開発サーバにおいては動作しますが、本番サーバでは import error になります。djangoforms.py をアプリケーションにコピーすれば動作しました。)

models.py

from google.appengine.ext import db
from google.appengine.ext.db.polymodel import PolyModel

class SeedKind(PolyModel):
    pass

class Family(SeedKind):
    name = db.StringProperty(required=True)
    link = db.LinkProperty()
    note = db.TextProperty()


views.py

import os
from google.appengine.ext.webapp import template
from google.appengine.ext.db import djangoforms
from django.core.context_processors import csrf
from django.http import HttpResponse
import models

class FamilyForm(djangoforms.ModelForm):
    class Meta:
        model = models.Family
        exclude = ['_class']

def home(request):
    path = os.path.join(os.path.dirname(__file__), 'index.djhtml')
    if request.method == 'POST':
        form = FamilyForm(request.POST)
        if form.is_valid():
            context = {'success': 'True'}
        else:
            context = {'success': 'False'}
    else:
        form = FamilyForm()
        context = {'success': 'None'}
    context['form'] = form
    context.update(csrf(request))
    return HttpResponse(template.render(path, context))


先に謝っておきますと home 関数の実装は洗練されてません。ひとまず動かしただけで、これから学習しようと思っています。render_to_response を使ってみたのですが、テンプレートファイルが NotFound になってしまったので暫定的に。

index.djhtml

<html>
    <body>
        <p>{{ success }}</p>
        <form action="/" method="post">{% csrf_token %}
            {{ form.as_p|safe }}
            <input type="submit" value="Submit" />
        </form>
    </body>
</html>


やってみてつまづいた点は2つ。

  • PolyModel を継承したモデルで ModelForm を使ったら class フィールドが表示された
    • exclude = ['_class'] で解決
  • form.as_p を実行したら < > がエスケープされて表示された
    • |safe で解決


exclude = ['_class'] は、djangoforms.BaseModelForm のコードをみると、instance.properties().iteritems() としているので、Family.properties().iteritems() としてみたら _class がいたのでございます。