【问题标题】:Django InlineFormSet validationDjango InlineFormSet 验证
【发布时间】:2014-07-16 14:06:00
【问题描述】:

我有一个BaseInlineFormSet,我想根据子字段上的值验证父表单中的字段。正如the docs 中所见,进行自定义验证的唯一方法是clean(),但我找不到将错误添加到父表单的方法,仅适用于子表单。

在下面的代码中,我构建了一个公式。每个变量都来自一个内部表单,如果全局公式不验证,我想在父表单字段中添加错误formula

class CustomInlineFormSet(BaseInlineFormSet):
    def clean(self):
        formula = self.instance.formula
        variables = []
        for form in self.forms:
            if 'formula_variable' in form.cleaned_data:
                variables.append(form.cleaned_data['formula_variable'])

        valid, msg = validate_formula(formula, variables)
        if not valid:
            WHAT HERE???

【问题讨论】:

  • 你试过self.add_error('formula', 'formula does not validate')吗?
  • 我得到一个AttributeError,因为self 没有属性add_error

标签: django django-forms


【解决方案1】:

看看这些链接:

Validation of dependant inlines in django admin

django - How to cross check ModelAdmin and its inlines?

但似乎要点是:

所以你需要做的是使用前两个链接作为指导进行一些黑客攻击。

【讨论】:

    【解决方案2】:

    感谢Russell Keith-Magee,我设法解决了这个问题。我在这里详细说明答案以供将来参考。

    我做错了,InlineFormSet 不是进行我需要的那种验证的正确位置,它应该在父 ModelForm 中完成。但是父ModelForm无权访问子FormSet,所以我只需要将FormSet作为参数传递给ModelForm。所以事情现在看起来像这样:

    观点:

    class FormulaCreate(CreateView):
        model = Formula
        template_name = "whatever.html"
    
        def get_context_data(self, **kwargs):
            context = super(ParameterRatioCreate, self).get_context_data(**kwargs)
            if self.request.POST:
                formset = FormulaVariablesFormSet(self.request.POST, instance=self.object)
                context['form'] = FormulaForm(formset=formset, data=self.request.POST, instance=self.object)
                context['formset'] = formset
            else:
                formset = FormulaVariablesFormSet(instance=self.object)
                context['form'] = FormulaForm(formset=formset, instance=self.object)
                context['formset'] = formset
    
            return context
    
        def form_valid(self, form):
            context = self.get_context_data()
            form = context['form']
            formset = context['formset']
            if form.is_valid() and formset.is_valid():
                ratio = form.save()
                formset = FormulaVariablesFormSet(self.request.POST, instance=ratio)
                if formset.is_valid():
                    formset.save()
                    self.object = ratio
                    return redirect(self.get_success_url())
    
            context['formset'] = formset
            return self.render_to_response(context)
    

    表格:

    class FormulaForm(forms.ModelForm):
        class Meta:
            model = Formula
    
        def __init__(self, formset, *args, **kwargs):
            self.formset = formset
            super(FormulaForm, self).__init__(*args, **kwargs)
    
        def clean(self):
            variables = {}
            for form in self.formset:
                if form.is_valid() and 'formula_variable' in form.cleaned_data:
                    variables[form.cleaned_data['formula_variable']] = 1
    
            if 'formula' in self.cleaned_data:
                formula = self.cleaned_data['formula']
                valid, msg = do_formula(formula, variables)
                if not valid:
                    self._errors['formula'] = self.error_class([msg])
                    del self.cleaned_data['formula']
    
            return self.cleaned_data
    

    FormSet:

    FormulaVariablesFormSet = inlineformset_factory(Formula,
                                                    FormulaVariable,
                                                    extra=1)
    

    【讨论】:

      猜你喜欢
      • 2018-06-02
      • 2023-02-04
      • 1970-01-01
      • 2016-09-20
      • 1970-01-01
      • 2012-12-19
      • 1970-01-01
      • 1970-01-01
      • 2018-03-12
      相关资源
      最近更新 更多