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

问题描述

我有2个模型,父亲儿子

我有一个页面可以注册父亲。在同一页上,我有一个表单来注册 Son

I have a page to register Father. On the same page I have a formset to register Son.

页面上有一个按钮more添加另一个父亲及其各自的儿子在同一页。

On page has a button "more" to add another Father and their respective Son on the same page.

有没有人使用 CreateView 的任何示例?

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
)

现在,将它与您的 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 插件保持添加新的内联表单:

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中的多个窗体和窗体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 02:39