CreateView 中的多个表单和表单集
Posted
技术标签:
【中文标题】CreateView 中的多个表单和表单集【英文标题】:Multiple Forms and Formsets in CreateView 【发布时间】:2012-09-16 10:36:07 【问题描述】:我有 2 个模型,Father
和 Son
。
我有一个页面可以注册Father
。在同一页面上,我有一个要注册 Son
的表单集。
页面上有一个“更多”按钮,用于在同一页面上添加另一个Father
和它们各自的Son
。
有人有使用CreateView
的例子吗?
【问题讨论】:
我尝试了Burhan给出的解决方案,但遇到了一些问题,包括avances123提到的问题。然后我找到了这篇博文:kevindias.com/writing/…,它有效。 【参考方案1】:基于类的视图还是新的,所以我会写出来。过程很简单:
首先,为您的对象创建表单。将重复其中一种形式。在这里没有什么特别可做的。
class SonInline(ModelForm):
model = Son
class FatherForm(ModelForm):
model = Father
然后,创建您的formset
:
FatherInlineFormSet = inlineformset_factory(Father,
Son,
form=SonInline,
extra=1,
can_delete=False,
can_order=False
)
现在,将其与您的 CreateView
集成:
class CreateFatherView(CreateView):
template_name = 'father_create.html'
model = Father
form_class = FatherForm # the parent object's form
# On successful form submission
def get_success_url(self):
return reverse('father-created')
# Validate forms
def form_valid(self, form):
ctx = self.get_context_data()
inlines = ctx['inlines']
if inlines.is_valid() and form.is_valid():
self.object = form.save() # saves Father and Children
return redirect(self.get_success_url())
else:
return self.render_to_response(self.get_context_data(form=form))
def form_invalid(self, form):
return self.render_to_response(self.get_context_data(form=form))
# We populate the context with the forms. Here I'm sending
# the inline forms in `inlines`
def get_context_data(self, **kwargs):
ctx = super(CreateFatherView, self).get_context_data(**kwargs)
if self.request.POST:
ctx['form'] = FatherForm(self.request.POST)
ctx['inlines'] = FatherInlineFormSet(self.request.POST)
else:
ctx['form'] = Father()
ctx['inlines'] = FatherInlineFormSet()
return ctx
最后,模板如下:
关键部分是 jquery django-dynamic-formset 插件,它不断添加新的内联表单:
<form id="father-form" method="POST" enctype="multipart/form-data" action=".">
% csrf_token %
<div class="row">
% for f in form %
<div class="span3"> f.label <br /> f
% if f.errors %
% for v in f.errors %
<br /><span style="color:red;"> v </span>
% endfor %
% endif %
</div>
% endfor %
</div>
<hr />
<h2>Sons:</h2>
<table class="table-striped">
<table>
% for f2 in inlines %
<tr id=" f2.prefix -row">
% for i in f2 %
<td>
i % if i.errors %<span style="color:red;"> i.errors </span>% endif %
</td>
% endfor %
</tr>
% endfor %
</table>
inlines.management_form
<input type="submit" class="btn btn-primary" value="Go Go Gadget →">
</form>
<script type="text/javascript">
$(function()
$('#father-form tr').formset(
prefix: ' inlines.prefix '
);
)
</script>
【讨论】:
这不会调用 formset.save() 所以没有儿子被保存。 儿子也没有得救以上是关于CreateView 中的多个表单和表单集的主要内容,如果未能解决你的问题,请参考以下文章
如何将引导类添加到模板中的 Django CreateView 表单字段?
我可以在 django 中的单个表单中使用多个表单集,如果可以的话如何?
Django Createview根据外键的id保存表单并重定向到页面
Django 1.3 CreateView/ModelForm:unique_together 验证,其中一个字段从表单中排除