web-dev-qa-db-ja.com

django-検証前にフィールドを処理/クリーンアップする方法

フォームをクリーンアップした後でのみ検証する必要があるフォームがあります。

form.is_valid()を実行するとどうなりますか?フォームがクリーンアップされ、そのクリーンアップされたバージョンのフォームが検証されますか?

私が現時点で得ている動作は、クリーニングの前にフィールドが検証に合格しなかった場合、クリーニングによってパスが成功したとしても、is_valid()Falseを返します。

私は何か間違ったことをしていますか?

コード:

_# View
class ContactForm(forms.Form):
    message = forms.CharField(widget=forms.Textarea, max_length=5)

    def clean_message(self):
        message = self.cleaned_data['message']
        return message.replace('a', '') # remove all "a"s from message

def contact(request):
    if request.method == 'POST':
        if form.is_valid():
            return HttpResponseRedirect('/contact/on_success/')
        else:
            return HttpResponseRedirect('/contact/on_failure/')
_

メッセージが5文字未満の場合にform.is_valid()Trueを返すようにしたい[〜#〜] not [〜#〜]aを含む!

clean_<fieldname>()の後でto_python()の前にrun_validators()を実行することはできますか?それとも別の方法でこれを行うべきですか?

28
Acorn

フォーム検証のプロセス(およびその正しい順序)は、非常によく文書化されていると思います。 http://docs.djangoproject.com/en/dev/ref/forms/validation/#form-and-field-validation

コードを共有していただけませんか?すべてのフォームフィールドにcleanメソッドがあり、to_pythonvalidaterun_validatorsをこの順序で実行します。 to_pythonはウィジェットの生の値を受け入れ、それをpythonタイプに強制します。validateは強制された値を受け取り、フィールド固有の検証を実行します。

指定されたコードに関して更新された回答

clean_messageは、他のすべての検証がto_pythonvalidate、そして最も重要なのはrun_validatorsのように実行された後に呼び出されます。最後のメソッドは、max_length制約に違反していないことを確認すると思います。したがって、後でデータを変更しても影響はありません。

解決策は、ここでValidationErrorをレイズすることです。 max_lengthを削除すると、入力の長さの検証が回避されます。

class ContactForm(forms.Form):
    message = forms.CharField(widget=forms.Textarea)

    def clean_message(self):
        message = self.cleaned_data['message']
        message = message.replace('a', '') # remove all "a"s from message
        if len(message) >= 5:
            raise ValidationError('Too many characters ...')
        return message
35
Reiner Gerecke

補足として、is_valid()Falseを返すときに、フォーム内に_self.errors_を出力して理由を確認できます。

is_valid()コードを監視する場合、これはフォーム_is_bound_をチェックし、_self.errors_は空です

2
Nicolas Rojo

CharFieldを上書きできます。

class CustomCharField(forms.CharField):
    def clean(self, value):
        return super().clean(value.replace('a', ''))

次に、それをフォームで使用できます

class ContactForm(forms.Form):
    message = CustomCharField(widget=forms.Textarea)
0
Qwarky