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

Dar*_*one 5 django django-forms

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

管理文件

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]
Run Code Online (Sandbox Code Playgroud)

模型.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'
    )
Run Code Online (Sandbox Code Playgroud)

表格.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?
Run Code Online (Sandbox Code Playgroud)

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

我也尝试过在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
Run Code Online (Sandbox Code Playgroud)

但是没有打印任何内容,因此似乎无法访问它?

RHS*_*159 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()



Run Code Online (Sandbox Code Playgroud)