单个django ModelForm中的多个模型?

Jas*_*ebb 89 python django django-forms

是否有可能ModelForm在django中包含多个模型?我正在尝试创建个人资料编辑表单.所以我需要包含User模型 UserProfile模型中的一些字段.目前我正在使用这样的2个表单

class UserEditForm(ModelForm):

    class Meta:
        model = User
        fields = ("first_name", "last_name")

class UserProfileForm(ModelForm):

    class Meta:
        model = UserProfile
        fields = ("middle_name", "home_phone", "work_phone", "cell_phone")
Run Code Online (Sandbox Code Playgroud)

有没有办法将这些整合到一个表单中,或者我只需要创建一个表单并处理数据库加载并保存自己?

Zac*_*ach 86

您可以在一个<form>html元素的模板中显示两个表单.然后在视图中单独处理表单.您仍然可以使用form.save()而不必处理数据库加载并自行保存.

在这种情况下,您不应该需要它,但如果您要使用具有相同字段名称的表单,请查看prefixkwarg中的django表单.(我在这里回答了一个问题).

  • 使基于类的视图能够显示多个表单和模板然后将它们组合到同一个`<form>`元素中的简单方法是什么? (6认同)
  • 但是如何?通常一个 `FormView` 只有一个分配给它的 `form_class`。 (2认同)

Mia*_*eng 9

您可以尝试使用这段代码:

class CombinedFormBase(forms.Form):
    form_classes = []

    def __init__(self, *args, **kwargs):
        super(CombinedFormBase, self).__init__(*args, **kwargs)
        for f in self.form_classes:
            name = f.__name__.lower()
            setattr(self, name, f(*args, **kwargs))
            form = getattr(self, name)
            self.fields.update(form.fields)
            self.initial.update(form.initial)

    def is_valid(self):
        isValid = True
        for f in self.form_classes:
            name = f.__name__.lower()
            form = getattr(self, name)
            if not form.is_valid():
                isValid = False
        # is_valid will trigger clean method
        # so it should be called after all other forms is_valid are called
        # otherwise clean_data will be empty
        if not super(CombinedFormBase, self).is_valid() :
            isValid = False
        for f in self.form_classes:
            name = f.__name__.lower()
            form = getattr(self, name)
            self.errors.update(form.errors)
        return isValid

    def clean(self):
        cleaned_data = super(CombinedFormBase, self).clean()
        for f in self.form_classes:
            name = f.__name__.lower()
            form = getattr(self, name)
            cleaned_data.update(form.cleaned_data)
        return cleaned_data
Run Code Online (Sandbox Code Playgroud)

用法示例:

class ConsumerRegistrationForm(CombinedFormBase):
    form_classes = [RegistrationForm, ConsumerProfileForm]

class RegisterView(FormView):
    template_name = "register.html"
    form_class = ConsumerRegistrationForm

    def form_valid(self, form):
        # some actions...
        return redirect(self.get_success_url())
Run Code Online (Sandbox Code Playgroud)


J E*_*Eti 5

我在我的项目中使用了django betterformsMultiForm 和 MultiModelForm。不过,代码还可以改进。例如,它依赖于 django.6,3.+ 不支持它,但所有这些都可以轻松修复

这个问题在 StackOverflow 中已经出现了好几次 所以我认为是时候找到一种标准化的方法来解决这个问题了。