Django InlineFormSet验证

时间:2014-05-27 15:18:46

标签: django django-forms

我有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???

2 个答案:

答案 0 :(得分:3)

看看这些链接:

  

Validation of dependant inlines in django admin

  

django - How to cross check ModelAdmin and its inlines?

但似乎要点是:

所以你需要做的就是使用前两个链接作为指导。

答案 1 :(得分:0)

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

我做错了,InlineFormSet不是我需要的那种验证的正确位置,它应该在父模型中完成。但是父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)