【Django】Forms.pyって何!? バリデーション構築で混乱してきたので整理してみた

【Django】Forms.pyって何!? バリデーション構築で混乱してきたので整理してみた

【Django】Forms.pyって何!? バリデーション構築で混乱してきたので整理してみた

ちょっと混乱してきたDjangoにとってのMVC構成。
Djangoさん。入門レベルは何とか超えたかなと思っていたのですが…いったいFormsって何?

Models.py /Forms.py /Views.py 役割分担の正解は?

参考図書を漁りながらいろいろ作業を進めていくと【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でバリデーションと言うとこのクラスで行われるのが一般的である様です。

この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にバリデーションを流します。

forms.ModelFormのMateクラスを使ってmodelsを見せると。

Modelsに来る前に簡単なものはFormsで刎ねてしまおう

バリデーションについてはこんな理解であっているのだと思います。
入力からDB格納までの動作は下の形で流れているようです。

  1. HTML(Template)で入力操作
  2. 入力された値がViewsに送られる
  3. ViewsからFormsに値を送り1次チェック(大きな篩)
  4. FormsからModelsに値を送り2次チェック(細かい篩)
  5. ModelsからDBに値を送り保存

う~ん、なかなかですね。
そもそも、forms.ModelFormとか存在するくらいなのでFormsはMVCアーキテクチャの【 M 】担当って事でいいんだろうなぁ。

まとめ

バリデーション書き出したらModelsとFormsがゴチャゴチャしてきたのでまとめてみました。
結果として『FormsはModelsの役割を一部取出したもの』と考えるのが最良だろうと感じました。

この感じだと、まだまだ悩むポイント出てきそうです。
「住めば都」なんでしょうけど、今の所はLaravelの方が扱いやすく感じます。