CreateView 中的多个表单和表单集 [英] Multiple Forms and Formsets in CreateView

查看:18
本文介绍了CreateView 中的多个表单和表单集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个模型,FatherSon.

我有一个页面可以注册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 &rarr;"></表单><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 &rarr;">
</form>
<script type="text/javascript">
    $(function() {
        $('#father-form tr').formset({
            prefix: '{{ inlines.prefix }}'
        });
    })
</script>

这篇关于CreateView 中的多个表单和表单集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆