【Django】Forms.pyって何!? バリデーション構築で混乱してきたので整理してみた
【Django】Forms.pyって何!? バリデーション構築で混乱してきたので整理してみた
ちょっと混乱してきたDjangoにとってのMVC構成。
Djangoさん。入門レベルは何とか超えたかなと思っていたのですが…いったいFormsって何?
参考図書を漁りながらいろいろ作業を進めていくと【Forms.py】と言うファイルを作って作業される方が多い様子なので、私も真似して作成していきました。
ただ、書いていると「これはどっち?」と言うシーンが出てくるようになり混乱したわけです。
バリデーションってModels.pyじゃないの?
混乱の一番の元はValidationの設定でした。
LaravelだとDB構成に関する事はModelsで操作なのでValidationもModelsで行います。
でも、DjangoのWEB上の参考資料ではForms.pyで行ってる例が多数。
「じゃあFormsでやるのかな」と思いきやModelsでValidationの解説を行ってる人もいます。
もう結局何が正しいやら「訳が分からない」となってしまったのでした。
Forms.py はHTMLとModelsの間のモジュールと理解すると良いっぽい。
「ん?でもそのポジションってViews.pyなんじゃないの?」と…。
要はこいつらの立ち位置がよくわかってないんだなと気づいたので役割を整理してみました。
- Models.py :SQLのテーブル定義集。※ SAVE時のバリデーションはModelsが担当になる。
- Views.py :表示画面(HTML)へのデータの受渡役。paramsで送ったりPOSTを受けたりする。
- Forms.py :ViewsとModelsの仲介役。Viewsの受けた値をFormsに渡して検索したり、SAVE前にチェックしたりを担当。
- ○○.html :人とViewsの間のパネル。情報の表示/入力を担当、操作された値はViewsに送られる。
- urls.py :表示画面(HTML)の道先案内。目次役。
つまり、validationに関して言えばModelsでもFormsでも行えるけど、どの時点で操作するかが異なると言う事の様です。
Forms.pyで行うバリデーションはforms.Formクラスが担当
Djangoでバリデーションと言うとこのクラスで行われるのが一般的である様です。
1 2 3 |
Class HogeForm(forms.Form): name = forms.CharField(label='Name') email = forms.EmailField(label='Email', required=False) |
このemailに設定した必須マークの解除【required=False】がFormsでのバリデーションが一般的な理由みたいです。
Djangoではforms.Formにフィールド項目を用意すると自動的にrequired=Trueと認識される
これ、ModelsでNULL=TRUEにしててもダメで、Modelsに送る前に「値が無いのはダメでしょ!」と怒られると言う事。
それってModelsでバリデーション組んでも意味ないって事…ですよね。
forms.Formで使えるバリデーション
文字列か数値か等のフィールドタイプでどう変わるかまとめてみます。
バリデーション命令 | 使えるフィールド | チェック項目 | 入力値 | 備考 |
required | 全フィールド | 必須か否か | True = 必須 False = 自由 |
forms.Formに記載している場合 False指定しないと全てTrueになっている。 |
empty_value | テキスト系 | 空入力の許可 | True = 可 False = 否 |
半角スペースはrequired=Trueではエラーだが empty_value=Trueでは許可される |
min_length | テキスト系 | 最小文字数 | 整数値 | パスワードの○文字以上等での利用が考えられる |
max_length | テキスト系 | 最大文字数 | 整数値 | 一般的な文字数制限として利用 |
min_value | 数値系 | 最小値 | 整数値 | |
max_value | 数値系 | 最大値 | 整数値 | |
input_formats | 日付系 | Format正否 | %y = 年 %m = 月 %d = 日 %H = 時 %M = 分% S = 秒 |
input_formats=[‘%y/%m/%d’]とすると 2020/11/27という記述を求められる |
まだあるかもしれないけど、ざっと調べるとこんな感じ。
感覚的に「ざっくりしたバリデーション」に感じます。
で、調べてみると細かなバリデーションはModelsに担当か移るらしいです。
models.Modelで使えるバリデーション
こちらもザックリですがまとめてみます。
バリデーション命令 | 使えるフィールド | チェック項目 | 入力値 | 備考 |
max_length | テキスト系 | 最大文字数 | 整数値 | min_lengthは存在しない。 |
MinLengthValidator | テキスト系 | 最小文字数 | 整数値 | |
MaxLengthValidator | テキスト系 | 最大文字数 | 整数値 | 文字数入力規制。 ※max_lengthと同じ |
MinValurValidator | 数値系 | 最小値 | 整数値 | |
MaxValurValidator | 数値系 | 最大値 | 整数値 | |
EmailValidator | EmailField | Mailか否か | validataorsに追加するとチェックする | |
URLValodator | URLField | URLか否か | validataorsに追加するとチェックする | |
ProhibitNullCharactersValidator | 全フィールド | NULL | validataorsに追加するとNULL規制する | |
RegexValidator | テキスト系 | ルール準拠 | 正規表現 | 正規表現を使い入力規制を行う ※数字のみとか |
number_only | 数値系 | 数値か否か | validataorsに追加するとチェックする |
全然違うし、こちらの方がチェック項目が細かいみたいです。
models.Modelのバリデーションは【models.py】に記載します。
この時、forms.pyでは下の様に記載してmodels.pyにバリデーションを流します。
1 2 3 4 5 |
#forms.py 内に記載 class ContentsCreateForm(forms.ModelForm): class Meta: model = Contents fields = ('types', 'name', 'contents',) |
forms.ModelFormのMateクラスを使ってmodelsを見せると。
Modelsに来る前に簡単なものはFormsで刎ねてしまおう
バリデーションについてはこんな理解であっているのだと思います。
入力からDB格納までの動作は下の形で流れているようです。
- HTML(Template)で入力操作
- 入力された値がViewsに送られる
- ViewsからFormsに値を送り1次チェック(大きな篩)
- FormsからModelsに値を送り2次チェック(細かい篩)
- ModelsからDBに値を送り保存
う~ん、なかなかですね。
そもそも、forms.ModelFormとか存在するくらいなのでFormsはMVCアーキテクチャの【 M 】担当って事でいいんだろうなぁ。
まとめ
バリデーション書き出したらModelsとFormsがゴチャゴチャしてきたのでまとめてみました。
結果として『FormsはModelsの役割を一部取出したもの』と考えるのが最良だろうと感じました。
この感じだと、まだまだ悩むポイント出てきそうです。
「住めば都」なんでしょうけど、今の所はLaravelの方が扱いやすく感じます。
-
前の記事
【Django】django.core.exceptions.FieldError: Unknown field(s) () specified for 2020.11.25
-
次の記事
【Django】TemplateResponseMixin requires either a definition of ‘template_name’ or an implementation of ‘get_template_names() 2020.11.30
コメントを残す