web-dev-qa-db-ja.com

form.is_valid()がfalseの場合にデータにアクセスする方法

有効なDjangoフォームがある場合、form.cleaned_dataを使用してデータにアクセスできます。しかし、フォームが有効でない場合、つまりform.is_validがユーザーが入力したデータを取得するにはどうすればよいですか偽。

フォームセット内のフォームにアクセスしようとしているので、form.dataは単に混乱を与えているようです。

47
Greg

使用できます

form.data['field_name']

このようにして、フィールドに割り当てられた生の値を取得します。

42

http://docs.djangoproject.com/en/dev/ref/forms/validation/#ref-forms-validation を参照してください

第二に、検討している2つのフィールドの結合データが無効であると判断したら、cleaned_dataからそれらを削除することを忘れないでください。

実際、Djangoは現在、フォームにエラーがある場合、cleaned_dataディクショナリを完全に消去します。ただし、この動作は将来変更される可能性があるため、後のクリーンアップは悪い考えではありませんそもそも自分自身。

元のデータは常にrequest.POST


コメントは、ポイントはより洗練されたフィールドレベルの検証のように聞こえる何かをすることであることを示唆しています。

各フィールドには未検証のデータが与えられ、有効なデータを返すか、例外を発生させます。

各フィールドでは、元のコンテンツに対してあらゆる種類の検証を行うことができます。

17
S.Lott

私は同様の問題に苦しんでいて、ここで素晴らしい議論に出会いました: https://code.djangoproject.com/ticket/10427

十分に文書化されているわけではありませんが、ライブフォームの場合は、ウィジェット/ユーザーから見たフィールドの値を次のように表示できます。

form_name['field_name'].value()
13
Sam

多くの方法があります。あなたが選ぶことができるすべて。

フォームは次のようなものだと思います:

class SignupForm(forms.Form):
    email = forms.CharField(label='email')
    password = forms.CharField(label='password',
                               widget=forms.PasswordInput)

1-1。 requestから取得

def signup(req):
    if req.method == 'POST':
        email = req.POST.get('email', '')
        password = req.POST.get('password', '')

2-1。 raw valueフィールドに割り当てられ、フィールドのdata属性の値を返します

def signup(req):
    if req.method == 'POST':
        ...
        sf = SignupForm(req.POST)
        email = sf["email"].data
        password = sf["password"].data
        ...

2-2。フィールドに割り当てられた生の値を取得し、フィールドのvalue属性の値を返します

def signup(req):
    if req.method == 'POST':
        ...
        sf = SignupForm(req.POST)
        email = sf["email"].value()
        password = sf["password"].value()
        ...

2-3。フィールドに割り当てられたdictionaryを取得します

def signup(req):
    if req.method == 'POST':
        ...
        sf = SignupForm(req.POST)
        # print sf.data
        # <QueryDict: {u'csrfmiddlewaretoken': [u'U0M9skekfcZiyk0DhlLVV1HssoLD6SGv'], u'password': [u''], u'email': [u'hello']}>
        email = sf.data.get("email", '')
        password = sf.data.get("password", '')
        ...
8
Burger King

次のパターンを使用できます。

class MyForm(forms.Form):
    ...
    def clean(self):
        self.saved_data=self.cleaned_data
        return self.cleaned_data

あなたのコードで:

if form.is_valid():
    form.save()
    return Django.http.HttpResponseRedirect(...)
if form.is_bound:
    form.saved_data['....'] # cleaned_data does not exist any more, but saved_data does.

Form.dataを使用するのは良い解決策ではありません。理由:

  • フォームにプレフィックスがある場合、辞書キーはこのプレフィックスでプレフィックスされます。
  • Form.dataのデータは消去されません。文字列値のみがあります。
5
guettli

フォームセットを使用して同様の問題に遭遇しました。この例では、ユーザーに2番目の選択肢の前に1番目の選択肢を選択してもらいたいのですが、1番目の選択肢が別のエラーにヒットした場合、「2番目の前に1番目の選択肢を選択」エラーも表示されます。

1番目のフィールドのクリーンアップされていないデータを取得するために、フォームフィールドのcleanメソッド内でこれを使用しました。

dirty_rc1 = self.data[self.prefix + '-reg_choice_1']

次に、そのフィールドのデータの存在をテストできます。

if not dirty_rc1:
    raise ValidationError('Make a first choice before second')

お役に立てれば!

3
Dashdrum

フィールドのclean()メソッドまたはフォームのclean()メソッドのいずれかからデータにアクセスします。 clean()は、フォームが有効かどうかを判断する関数です。 is_valid()が呼び出されたときに呼び出されます。フォームのclean()には、cleaned_dataすべてのチェックアウトを確認するためにカスタムコードを実行できる場合にリストします。ウィジェットにはclean()もありますが、単一の渡された変数を使用します。フィールドのclean()メソッドにアクセスするには、サブクラス化する必要があります。例えば。:

class BlankIntField(forms.IntegerField):
    def clean(self, value):
        if not value:
            value = 0
        return int(value)

たとえば、空の値でチョークしないIntFieldが必要な場合は、上記を使用します。

次のようなフォームの種類のclean():

def clean(self):
    if self.cleaned_data.get('total',-1) <= 0.0:
        raise forms.ValidationError("'Total must be positive")
    return self.cleaned_data

また、各フィールドにclean_FIELD()関数を使用して、各フィールドを個別に検証できるようにすることができます(フィールドのclean()が呼び出された後)

1
priestc