Django 表单验证:在父表单中获取子表单数据

Posted

技术标签:

【中文标题】Django 表单验证:在父表单中获取子表单数据【英文标题】:Django form validation: get child form data in parent 【发布时间】:2020-05-01 05:11:34 【问题描述】:

我想知道在验证父级时是否可以访问内联表单。例如,如果我的设置如下所示:

admin.py

class ChildInline(nested_admin.NestedTabularInline):
    form = forms.ChildInlineForm
    model = models.Child
    extra = 0


@admin.register(models.Parent)
class ParentAdmin(nested_admin.NestedModelAdmin):
    form = forms.ParentForm
    inlines = [ChildInline]

models.py

class Parent(models.Model):
    name = models.CharField(max_length=10)

class Child(models.Model):
    name = models.CharField(max_length=10)
    parent = models.ForeignKey(
        Parent, on_delete=models.CASCADE, related_name='children'
    )

forms.py

class ChildForm(forms.ModelForm):
    class Meta:
        model = models.Child
        fields = '__all__'


class ParentForm(forms.ModelForm):
    class Meta:
        model = models.Parent
        fields = '__all__'

    def clean(self):
        super().clean()
        # How would I access the ChildForm here?

有没有办法从ParentForm.clean() 访问ChildForm 我意识到我可以在子级中获取父级数据-但我的用例涉及多个具有要传递给父级的数据的子级-我想在顶层进行验证(如果可能)。

我也尝试在 model.Parent.clean() 方法中进行验证,但 Child 模型保存在父模型之后,所以这似乎也不是首发。

离开下面的答案我也尝试过使用自定义表单集:

class ParentFormSet(forms.BaseModelFormSet):

    def clean(self):
        if any(self.errors):
            return
        for f in self.forms:
            print(f.cleaned_data)

class ParentForm(forms.ModelForm):
    class Meta:
        model = models.Parent
        fields = '__all__'
    formset = ParentFormSet

但是什么都没有打印,所以似乎无法访问?

【问题讨论】:

我不确定,但也许这会有所帮助! ***.com/questions/23893167/… clean() 恐怕不会为非内联表单集调用。 【参考方案1】:

您也许可以覆盖ModeAdmin 方法save_formset()? https://docs.djangoproject.com/en/2.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_formset


@admin.register(models.Parent)
class ParentAdmin(nested_admin.NestedModelAdmin):
    form = forms.ParentForm
    inlines = [ChildInline]

    def save_formset(self, request, form, formset, change):
        parent_form = form
        for form_set_form in formset:
            if formset_form.is_valid():
                form_set_form_data = form_set_form.cleaned_data
                # do some validation here...
        formset.save()



【讨论】:

如果你在这里提出 ValidationError 会很烦人,网络服务器会崩溃。

以上是关于Django 表单验证:在父表单中获取子表单数据的主要内容,如果未能解决你的问题,请参考以下文章

为什么使用动态输入值进行此表单验证不起作用?

子表单可以在父表单之外吗?

onclick 打开子窗口并提交表单

为啥这种带有动态输入值的表单验证不起作用?

在父级为表单的子报表中滚动

antd 父组件获取子组件中form表单的值