本文介绍了CreateView 中的多个表单和表单集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有两个模型,Father
和 Son
.
我有一个页面可以注册Father
.在同一页面上,我有一个用于注册 Son
的表单集.
页面上有一个更多"按钮,可以在同一页面上添加另一个父亲
和他们各自的儿子
.
有人有使用 CreateView
的例子吗?
解决方案
基于类的视图仍然是新的,所以我会写出来.过程很简单:
首先,为您的对象创建表单.其中一种形式将被重复.这里没有什么特别的事情要做.
class SonInline(ModelForm):模型 = 儿子类FatherForm(ModelForm):模型 = 父亲
然后,创建您的formset
:
FatherInlineFormSet = inlineformset_factory(Father,儿子,形式=SonInline,额外=1,can_delete=假,can_order=假)
现在,将其与您的 CreateView
集成:
class CreateFatherView(CreateView):模板名称 = 'father_create.html'模型 = 父亲form_class = FatherForm # 父对象的表单# 成功提交表单def get_success_url(self):return reverse('父亲创造的')# 验证表单def form_valid(self, form):ctx = self.get_context_data()内联 = ctx['内联']如果 inlines.is_valid() 和 form.is_valid():self.object = form.save() # 保存父亲和孩子返回重定向(self.get_success_url())别的:返回 self.render_to_response(self.get_context_data(form=form))def form_invalid(self, form):返回 self.render_to_response(self.get_context_data(form=form))# 我们用表单填充上下文.我在这里发送# `inlines` 中的内联表单def get_context_data(self, **kwargs):ctx = super(CreateFatherView, self).get_context_data(**kwargs)如果 self.request.POST:ctx['form'] = FatherForm(self.request.POST)ctx['inlines'] = FatherInlineFormSet(self.request.POST)别的:ctx['form'] = 父亲()ctx['inlines'] = FatherInlineFormSet()返回 ctx
最后,这是模板:
关键部分是 jquery django-dynamic-formset 插件,不断添加新的内联表单:
{% 结束为 %}
<小时/><h2>儿子们:</h2><table class="table-striped"><表格>{% for f2 inline %}<tr id="{{ f2.prefix }}-row">{% for i in f2 %}<td>{{ i }}{% if i.errors %}<span style="color:red;">{{ i.errors }}</span>{% endif %}</td>{% 结束为 %}</tr>{% 结束为 %}{{ inlines.management_form }}<input type="submit" class="btn btn-primary" value="Go Go Gadget →"></表单><script type="text/javascript">$(函数(){$('#father-form tr').formset({前缀:'{{ inlines.prefix }}'});})
I have 2 models, Father
and Son
.
I have a page to register Father
. On the same page I have a formset to register Son
.
On page has a button "more" to add another Father
and their respective Son
on the same page.
Does anyone have any examples using CreateView
?
解决方案
Class based views are still new, so I'll write this out. The process is simple:
First, create the forms for your objects. One of the forms will be repeated. Nothing special to be done here.
class SonInline(ModelForm):
model = Son
class FatherForm(ModelForm):
model = Father
Then, create your formset
:
FatherInlineFormSet = inlineformset_factory(Father,
Son,
form=SonInline,
extra=1,
can_delete=False,
can_order=False
)
Now, to integrate it with your 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
Finally, here is the template:
The key part is the jquery django-dynamic-formset plugin that keeps adding new inline forms:
<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>
这篇关于CreateView 中的多个表单和表单集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!