类似于@james 答案(我有一个类似的起点),但它不需要通过 POST 数据接收表单名称。相反,它使用自动生成的前缀来确定哪些表单接收到 POST 数据、分配数据、验证这些表单,最后将它们发送到适当的 form_valid 方法。如果只有 1 个绑定表单,它会发送该单个表单,否则它会发送一个{"name": bound_form_instance}
字典。
它与forms.Form
可以分配前缀的其他“表单行为”类兼容(例如 django 表单集),但尚未制作 ModelForm 变体,但您可以在此视图中使用模型表单(请参阅下面的编辑)。它可以处理不同标签中的表单、一个标签中的多个表单或两者的组合。
代码托管在 github ( https://github.com/AlexECX/django_MultiFormView ) 上。有一些使用指南和一个涵盖一些用例的小演示。目标是让类感觉尽可能接近 FormView。
这是一个带有简单用例的示例:
视图.py
class MultipleFormsDemoView(MultiFormView):
template_name = "app_name/demo.html"
initials = {
"contactform": {"message": "some initial data"}
}
form_classes = [
ContactForm,
("better_name", SubscriptionForm),
]
# The order is important! and you need to provide an
# url for every form_class.
success_urls = [
reverse_lazy("app_name:contact_view"),
reverse_lazy("app_name:subcribe_view"),
]
# Or, if it is the same url:
#success_url = reverse_lazy("app_name:some_view")
def get_contactform_initial(self, form_name):
initial = super().get_initial(form_name)
# Some logic here? I just wanted to show it could be done,
# initial data is assigned automatically from self.initials anyway
return initial
def contactform_form_valid(self, form):
title = form.cleaned_data.get('title')
print(title)
return super().form_valid(form)
def better_name_form_valid(self, form):
email = form.cleaned_data.get('email')
print(email)
if "Somebody once told me the world" is "gonna roll me":
return super().form_valid(form)
else:
return HttpResponse("Somebody once told me the world is gonna roll me")
模板.html
{% extends "base.html" %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ forms.better_name }}
<input type="submit" value="Subscribe">
</form>
<form method="post">
{% csrf_token %}
{{ forms.contactform }}
<input type="submit" value="Send">
</form>
{% endblock content %}
编辑 - 关于 ModelForms
Welp,在查看了 ModelFormView 之后,我意识到创建 MultiModelFormView 并不容易,我可能还需要重写 SingleObjectMixin。同时,只要在模型实例中添加“instance”关键字参数,就可以使用 ModelForm。
def get_bookform_form_kwargs(self, form_name):
kwargs = super().get_form_kwargs(form_name)
kwargs['instance'] = Book.objects.get(title="I'm Batman")
return kwargs