formの扱い方 まとめ
フォームについて
リンク先
forms.pyに使うlabelの働きforms.py外で定めなければならないもの
formの入力データを返す方法(cleaned_data)
フォームにはforms.pyを使う方法とformのhtmlをテンプレートに挿入する方法がある。
①forms.pyについて記載する。
forms.pyの使いかたのイメージ
views.pyでお馴染みのrender(request,"hoge/hoge.html",context)を使う。contextにforms.pyの内容をぶち込む。forms.pyを作るのはフォームの内容は複雑だからforms.pyで作っておいて必要なぶち込み要素だけ呼び出すってイメージ。
手順
ディレクトリはアプリケーションで指定したところ。
そこにforms.pyを作成する。
forms.py は以下のようにクラス指定し入力フォームを要素を決めてあげる。
例
forms.py
from django import forms class RegisterForm(forms.Form): user = forms.CharField() email = forms.EmailField() password = forms.CharField()
これで入力フォームができる。
これを記述するとinputタグとほぼ同じ役割があると思って良い。
inputタグの場合class指定、placeholder指定やname指定していたけど、それらはFieldの括弧内で指定することになる。
下に記述する。
参考までにinputタグと同じようにclassやplaceholderをどのようにすれば設定できるのかを書く。
ドキュメントにはこう書いてある。
”フォームフィールドは、HTML "ウィジェット” - ユーザーインターフェイスの装置の一つです - としてブラウザ内のユーザーに表されます。それぞれのフィールドタイプは、適切なデフォルトの Widget class を持っていますが、これらは必要に応じてオーバーライドできます。”
https://docs.djangoproject.com/ja/2.1/topics/forms/#the-django-form-class
つまり何が言いたいかって言うと、()に何かを記すことは、ブラウザを使っているユーザに意図したとおりの見え方に設定することなのだ。
ここでは、フィールド括弧内の内容だけを書く。
widget=forms.TextInput(attrs={"class":"form-control","placehplder":"User Name","name":"user name",})
typeについてはここに含めてもいいと思うけど、ドキュメントは独立して書く方法があるとしている。
ウィジェット | Django documentation | Django
追記
widgetの種類はいっぱいある。これらについて一応仮説がある。
widget=forms.TextInput()の部分で、TextInputの他にEmailInput,Textareaの種類がある。
まずinputタグかtextareaタグかに分かれる。inputタグ系はTextInput,EmailInputである。
Textareaはtextareaタグだ。次にinputタグ系はそれぞれtypeをInput前に表現している。
だからinputタグ系を選んだら、自動的にバリエーション機能も持つことになる。
②formのhtmlをテンプレートに挿入する方法
forms.pyを用いた方法はrenderを使って記述する方法で、②の方法はテンプレートに挿入する方法なのでクラス別汎用ビューだろうがrenderを使っていようが使える方法。
まずhtmlを準備
<form method="POST" > <input class="form-control " type="text" placeholder="message to me" > <button type="submit">Submit</button> </form>
これをテンプレートに挿入
{% include "hoge" %}
追記:forms.pyの書き方
forms.pyでforms.Formを継承してフォームを書く方法にはもう一つの方法がある。
参照先:
https://djangogirlsjapan.gitbooks.io/workshop_tutorialjp/content/django_forms/
従来の書き方を記すと
from django import forms class RegisterForm(forms.Form): user = forms.CharField() email = forms.EmailField(widget=forms.EmailInput) password = forms.CharField()
こんな感じだ。ただmodels.pyのRegisterFormを利用するとこんな書き方で済ませることができる。
from django import forms from hoge.models import Register class RegisterForm(forms.Form): class Meta: model = Register
次にviews.pyと表示されるhtml関係をテーマにする
views.py にて
from .forms import RegisterForm def user_register(request) : form = RegisterForm(request.POST) context = {"form" : form } return render(request, 'register.html', context)
説明:request.POSTのデータを受け取ったformのオブジェクトを作成する。
そしてregister.htmlの{{ form }}を記載したところに入力フォームが表示されることになる。
イメージ的には下記のようになる。
<form method="POST">{% csrf_token %} {{ form }} <button >submit</button>
これでhtmlに反映されるようになる。
views.pyについてより実用的なコードに変換すると以下になる。
from .forms import RegisterForm def user_register(request) : if request.method == POST: form = RegisterForm(request.POST) if form.is_valid(): return HttpResponseRedirect('/thanks/') else: pass context = {"form" : form } return render(request, 'register.html', context)