5

次のような比較的標準的なRegistrationFormがあります。

class RegisterForm(forms.Form):
    username = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'username'}), initial='')
    email = forms.EmailField(widget=forms.TextInput(attrs={'placeholder': 'email'}), initial='')
    password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'password'}), initial='')
    password_repeat = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'retype password'}), initial='')

ユーザーが1つ以上のフィールドに入力し忘れたときにエラーを返すクリーンなメソッドを作成するにはどうすればよいですか?(つまり、「メールフィールドに入力するのを忘れた」)

clean()メソッドで次の2つのオプションを試しました(例としてpasswordフィールドとpassword_repeatフィールドを使用します)。

password = self.cleaned_data['password']
password_repeat = self.cleaned_data['password_repeat']
# initial values are set to '' for all fields, see above.
if password == '':
    raise forms.ValidationError("You forgot to type in a password.")
elif password_repeat == '':
        raise forms.ValidationError("You forgot to retype your password.")

最初のオプションは次を返します。

/homepage/のKeyError

'パスワード'


try:
    password = self.cleaned_data['password']
    password_repeat = self.cleaned_data['password_repeat']
except KeyError(password):
    raise forms.ValidationError("You forgot to fill in the password field.")

2番目のオプションは次を返します。

/homepage/のUnboundLocalError

割り当て前に参照されるローカル変数「パスワード」


残りのフィールドもチェックできるソリューションを提供できる場合はボーナスポイント(ユーザーが正常に送信したデータにバインドされたフォームを返すことができるようにするため)。

4

3 に答える 3

5

すべてのフィールドタイプで使用可能なプロパティを使用できますrequired。これにより、このタイプの検証が自動的に実行されます。したがって、コードは次のようになります。

class RegisterForm(forms.Form):
    username = forms.CharField(
        widget = forms.TextInput(attrs = {'placeholder': 'username'}),
        required = True)
    email = forms.EmailField(
        widget = forms.TextInput(attrs = {'placeholder': 'email'}),
        required = True)
    password = forms.CharField(
        widget = forms.PasswordInput(attrs = {'placeholder': 'password'}),
        required = True)
    password_repeat = forms.CharField(
        widget = forms.PasswordInput(attrs = {'placeholder': 'retype password'}),
        required = True)

initial = ''注:上記のように、これらのパラメーターも省略できると思います。

質問で言及したエラーが発生する理由は実際にはわかりません。おそらく、関連するコードを投稿することができますviews.pyか?これは、実装するメソッドcleaned_dataの最後に戻る必要があるためである可能性があります。clean

また、この方法の使用はclean完全に正しくありません。フォームとフィールドの検証に関するドキュメントのこのページを参照すると、単一のフィールドを検証するために特定のclean_<fieldname>方法を使用していることがわかりますclean_password_repeatclean検証に複数のフィールドが同時に含まれる場合は、この方法を使用するのが適切です。この方法の1つの例は、2つのパスワードフィールドの入力が一致するかどうかを確認することです。

class RegisterForm(forms.Form):
    # field definitions (above)

    def clean(self):
        password = self.cleaned_data['password']
        password_repeat = self.cleaned_data['password_repeat']
        if password != password_repeat:
            raise forms.ValidationError(u"Passwords do not match.")
        return cleaned_data

注:コードはテストされていません。

これがお役に立てば幸いです。

于 2012-11-21T23:42:09.070 に答える
1

django 1.2以降、モデルに検証コードを記述できるようになりました。私は常にモデル側でビジネスルールを書きます:

これはあなたのモデルです:

from django.db import models
class Issue(models.Model):
    ....

    def clean(self): 
        rules.Issue_clean(self)

#I write business rules into another file ...
def Incidencia_clean( instance ): 
    import datetime as dt

    errors = {}

    #some business rules:     
    if not instance.dia_incidencia: 
        errors.setdefault('b1',[]).append(u'Falten...ranja')

    if not  instance.franja_incidencia: 
        errors.setdefault('b2',[]).append(u'Falten..nja')

    if instance.dia_incidencia < ( dt.date.today() + 
                                   dt.timedelta( days = -7) ): 
        errors.setdefault('b3',[]).append(u'''No es ... setmana)''')

    if instance.getDate() > datetime.now(): 
        errors.setdefault('b4',[]).append(u'''Encara ...itzat.''') 

    if len( errors ) > 0: 
        raise ValidationError(errors) 

テンプレートの場合:

{% if form.non_field_errors %}
      {% for error in form.non_field_errors %}
        {{error}}
      {% endfor %}
{% endif %}  

各フォームにルールを繰り返すよりも、モデルでビジネスルールを1回書く方が好きです。

于 2012-11-21T21:47:58.570 に答える
0

これは、dictのキーをステップスルーし、それらのいずれかが空の文字列またはその他のFalseのような値にマップされている場合に例外を発生させるスニペットです。例外は、dictのどのキーにエントリがないかを示します。

for key in self.cleaned_data:
    if not self.cleaned_data[key]:
        raise forms.ValidationError("You didn't fill in the {} form".format(key))

False空の文字列( 、、、など0ではない[])のみをテストする場合は、に変更if not self.cleaned_data[key]:if self.cleaned_data[key] == '':ます。

于 2012-11-21T21:49:32.523 に答える