forms.pyでバリデーションするときにハマった

こうなった

こんなのかいた

from django import forms
from django.forms import ModelForm

from qa.models import *
from qa.tools import confirm_str_lt_length, confirm_char_in_str, confirm_equal_str

class SignupForm(ModelForm):
    password = forms.CharField(label=u'パスワード', max_length=64,widget=forms.PasswordInput ,required=True)
    password2 = forms.CharField(label=u'パスワード(確認用)', max_length=64 ,widget=forms.PasswordInput,required=True)
    class Meta:
        model = User
        fields = ('email','nickname')

    def clean_email(self):
        email = self.cleaned_data['email']
        if not confirm_char_in_str('@',email):
            raise forms.ValidationError(u'有効なメールアドレスではありません')
        return email

    def clean_nickname(self):
        nickname = self.cleaned_data['nickname']
        if confirm_str_lt_length(nickname,3):
            raise forms.ValidationError(u'ニックネームは3文字以上にしましょう')
        return nickname

    #def clean_password2(self):
    #   password = self.cleaned_data['password']
    #   password2 = self.cleaned_data['password2']
    #   if confirm_str_lt_length(password,5):
    #       raise forms.ValidationError(u'パスワードは5文字以上にしましょう')
    #   if not confirm_equal_str(password,password2):
    #       raise forms.ValidationError(u'パスワードが異なるようです')
    #   return password

    def clean_password(self):
        password = self.cleaned_data['password']
        if confirm_str_lt_length(password,5):
            raise forms.ValidationError(u'パスワードは5文字以上にしましょう')
        return password

    def clean(self):
        cleaned_data = self.cleaned_data
        password = cleaned_data.get('password')
        password2 = cleaned_data.get('password2')
        if not confirm_equal_str(password,password2):
            raise forms.ValidationError(u'パスワードが異なるようです')
        return cleaned_data

注意点

  • 関数は clean_ で始める
    • そして clean_password のように実際にフォームやモデルで定義した名前しか使えない。最初はclean_password_number clean_password_match と分けていたが、そうはできない
  • password2のところはなぜかpasswordだとKeyErrorになる
    • なんだかよくわからないが、後ろの方の変数を使うといい、のか?
  • clean()を使いましょう

追記

@xxxxxx

ふむ Fromのcleanなんだが clean_フィールド名 clean 2つあって 個別のフィールドに対しての追加バリデーションは clean_フィールド名で 複数のフィールドにまたがるバリデーションはcleanフィールドでやるとよいよ