DjangoのForm生成が便利すぎる件について
最近はwicket使うことが多かったので久しぶりにpythonでdjango弄ってみました。
んでwicketは慣れるといろいろ便利なのでdjangoでも同じような機能ないかなーって思ってたんですが
djangoだとmodelクラスを継承したクラスのフォーム作成がほとんど自動でできてしまうとっても便利な機能があったのです!!気づかなかったw
(しかもvalidationまで自動でやってくれます!)
たとえば
class Blog(models.Model): title = models.CharField(max_length=255) content = models.TextField(models.Model) user = models.ForeignKey(auth_models.User)
というようなモデルがあったとします
このフォームを作成するために
class BlogForm(ModelForm): class Meta: model = Blog exclude = ('user',)
excludeはフォームのときに除外したいカラムを指定します
このようなフォームクラスを作成し、
views.pyで
def edit_blog(request): form = BlogForm() return render_to_response('blog.html', {'form':form})
テンプレート側で
<form method="POST" action=""> {{ fomr }} <input type="submit" /> </form>
とするだけでフォームができてしまうのです。
既存のデータを編集したい場合には
views.pyで
blog = Blog.objects.get(hogehoge) form = BlogForm(instance=blog) return render_to_response('blog.html', {'form':form})
とすれば既存データがセットされた形でフォームが出てきます。
データの検証とデータベースへの反映は
def write(request): blog = Blog(user=request.user) new_blog = BlogForm(request, blog) if new_blog.is_valid(): new_blog.save()
とすれば完了
new_blog = BlogForm(request)
とすると先ほどBlogFormの作成のときにexcludeに指定したuserが空のままなので怒られてしまうため、excludeしたデータを補填したインスタンスを生成して第二引数に渡してあげることでちゃんとしたデータが生成されます
is_valid()はフォームに入力されたデータが正しいものかを判断してくれます。
既存データのupdateは
blog = Blog.objects.get(hogehoge)
update_blog = BlogForm(request, blog)
if update_blog.is_valid();
update_blog.save()
でできます。
ちなみに自動で生成してくれるフォームはあくまで仮のものなのできれいにしたい場合は
<form> タイトル{{ form.title}}<br /> 内容{{form.content}}<br /> </form>
のように個々のカラムごとにinputタグのみ生成もできるのでこのようにするといいかもしれません。
ちなみに
{{form.as_p}}
{{form.as_ul}}
{{form.as_table}}
などとするとフォームを一連のp要素やul要素で成型してくれます。
あと
form.is_valid()でFalseが投げられたものをテンプレートの引数に渡すとそれぞれのフォームでエラーが起こった原因が表示されます
またこれも個々に出力したい場合は
{{form.errors.title}}
などとします。
細かい設定はドキュメントを見るといいと思いますがかなりわかりづらかったです・・・