7

ユーザーがフォームセットのフォームに不完全に入力してから削除のマークを付けると、フォームの処理がひどく停止します。削除されたフォームは、検証されないため、formset.cleaned_dataが機能しなくなり、フォームにcleaned_data属性がなくなります。formset.deleted_formsを繰り返し処理し、formset.formsからフォームを削除しようとすると、インデックスが範囲外であるためにformset.cleaned_dataがクラッシュします。

ユーザーがとにかく望まなかったこれらの無効なフォームをどのように処理する必要がありますか?

(これは私のエラーです、私はグーグルグループから説明をコピーしました)

djangoコードを調べると、次のように読み取れるため、エラーを理解できません。

def is_valid(self):
    """
    Returns True if form.errors is empty for every form in self.forms.
    """
    if not self.is_bound:
        return False
    # We loop over every form.errors here rather than short circuiting on the
    # first failure to make sure validation gets triggered for every form.
    forms_valid = True
    err = self.errors
    for i in range(0, self.total_form_count()):
        form = self.forms[i]
        if self.can_delete:                           <-------
            if self._should_delete_form(form):
                # This form is going to be deleted so any of its errors
                # should not cause the entire formset to be invalid.
                continue
        if bool(self.errors[i]):
            forms_valid = False
    return forms_valid and not bool(self.non_form_errors())

現時点では、これはエラーを回避するための私のコードです。

formFac = modelformset_factory(prm_model, extra = extra, can_delete = prm_can_delete )

if request.method == 'POST':
    formSet = formFac( request.POST )
    hi_ha_errors = False
    if formSet.is_valid():
        for form in formSet:
            if form not in formSet.deleted_forms:
                form.save()
        for form in formSet.deleted_forms:
            instance = form.instance
            if instance.pk:
                try:
                    instance.delete()
                except Exception, e:                    
                    form._errors.setdefault(NON_FIELD_ERRORS, []).append( 
                          'This row is referenced by others.'  )
                    hi_ha_errors = True

        if not hi_ha_errors:
            return HttpResponseRedirect( prm_url_next )     
4

1 に答える 1

0

full_clean()これを解決する方法は、Formset/ModelFormsetで使用されているForm/ModelFormのメソッドをオーバーライドすることです。

class MyModelForm(ModelForm):

    def full_clean(self, *args, **kwargs):
        super(MyModelForm, self).full_clean(*args, **kwargs)
        if hasattr(self, 'cleaned_data') and self.cleaned_data.get('DELETE', False):
            self._errors = ErrorDict()

フォーム削除ボックスがチェックされている場合、これによりエラーリストがクリアされます。フォームはエラーなしで表示されます。ただし、ユーザーが削除ボックスのチェックを外して再送信すると、フォームには通常どおりエラーが表示されます。

于 2018-10-18T22:26:07.640 に答える