在这种情况下,我通常会创建ExampleTroughModelForm并使ExampleModelForm成为其属性。然后在HTML中,我在不带表单标记的情况下呈现这两个文件,并将它们保存在一起。记得覆盖
save()
,
clean()
和
is_valid()
方法,以便正确保存和验证ExampleModelForm。
ExampleThroughModelForm的建议代码(未测试):
class ExampleThroughModelForm(ModelForm):
class Meta:
model = ExampleThrough
fields = '__all__'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Add custom prefix to avoid name clashes in case of same
# attribute name in ExampleModelForm and ExampleThroughModelForm
self.example_form = ExampleModelForm(data=kwargs.get('data'), instance=getattr(self.instance, 'example', None), prefix='example')
self.helper = FormHelper()
self.helper.form_tags = False
def save(self, **kwargs):
# The ExampleModelForm needs to be saved first in case you are just
# creating it. We can't have the through Model without this
saved_example_instance = self.example_form.save()
# Set the Example model on the ExampleThrough instance before saving
self.instance.example = saved_example_instance
# Save the ExampleThrough model
saved_example_through_instance = super().save(**kwargs)
return saved_example_through_instance
def clean(self):
# Here we also hook the calls to the clean method of the example form
# This is not necessary but if you have a custom clean method on the
# ExampleModelForm, you will want to call it when this form is cleaned
self.example_form.clean()
super().clean()
return self.cleaned_data
def is_valid(self)
# This is necessary because is_valid method sets the cleaned_data attribute
return self.example_form.is_valid() and super().is_valid()
请记住,在ExampleForm中,您还需要删除表单标记。
在具有用于呈现的脆格式的HTML中,它看起来像这样:
<form id="example-through-form" method="post" actions="{% url 'save-example-through' %}">
{% crispy form %}
{% crispy form.example_form %}
<!-- Submit input buttons omitted for brevity -->
</form>