提交时应该如何收集克隆的 Django 表单?

Posted

技术标签:

【中文标题】提交时应该如何收集克隆的 Django 表单?【英文标题】:How should cloned Django forms be collected on submission? 【发布时间】:2012-10-26 09:54:58 【问题描述】:

我正在使用标准的 Django 模型表单,然后在 html 模板中使用我们目前正在重新构建的应用程序系统。

棘手的一点(至少对我而言)是使用名为"SheepIt" 的 jQuery 插件向 HTML 动态添加额外表单的过程中的一个步骤,我想知道如何在相关视图。

SheepIt 比特:

$(document).ready(function()    
        var sheepItForm = $('#sheepItForm').sheepIt(
            separator: '',
            allowRemoveLast: true,
            allowRemoveCurrent: true,
            allowRemoveAll: false,
            allowAdd: true,
            allowAddN: false,
            minFormsCount: 1,
            iniFormsCount: 1
        );

    );

模板代码:

<div id="entry_form">
<form method="post" enctype="multipart/form-data" action="/enter/2/" id="sheepItForm">
    <fieldset id="sheepItForm_template">
                <a id="sheepItForm_remove_current">X</a>
                <div class="select"> form.select </div>
                <div class="text"> form.text </div>
                <div class="upload"> form.upload </div>
    </fieldset>

     <div id="sheepItForm_noforms_template">No Entries</div>

     <div id="sheepItForm_controls">
         <div id="sheepItForm_add"><a><strong>+</strong> Add Another Entry</a></div>
     </div> 

 formset.management_form 
<input type="submit" value="Proceed to Payment"> 
</form></div>

上面输出了一个带有按钮的小表单,可以使用 SheepIt 插件添加和删除表单的克隆。

通常,我们会通过以下方式收集表单数据:

form_data = request.POST.copy()

或类似的。我应该只遍历发布数据中收集的所有内容,还是有更好的“pythonic”方式来处理这些小克隆?也许将它们收集到一个表单集中,然后做类似的事情:

for f in formset.forms:
    if f.is_valid():
        f.save()

编辑: 以下是我目前正在修改和更改的一些视图代码:

    form = EntryForm_2_set.form()
    template_dict['form'] = form
    if request.method == 'POST':
        # from forms.py: EntryForm_2_set = forms.formsets.formset_factory(EntryForm_2, extra=0)
        formset = EntryForm_2_set(request.POST)
        if formset.is_valid():
            for f in formset.forms:
                if f.is_valid():
                    f.save()
            entry_url = reverse('entry-stage',kwargs='stage':3) 
            return HttpResponseRedirect(entry_url)
    else:
        formset = EntryForm_2_set()
        template_dict['formset'] = formset
    return render_to_response('submission-stage-two.html', template_dict, RequestContext(request)) 

各位有什么想法吗?

【问题讨论】:

Formsets 更适合此类事情,但您需要将其插入 SheepIt 以发送适当的数据。可能有一些特定于 django 的插件可用于动态数量的表单。 感谢 Rohan,我实际上已经做了一些扎根工作,我正在尝试 django-dynamic-formset 开始。 【参考方案1】:

最终自己解决了。

唯一剩下的就是在重新输入时填写表格。

我之前缺少的是具有灵活性的表单集工厂的实现。如果有更优雅的解决方案,我很想听听有关未来更新的建议。

大家好。


查看代码:

# Create the formset factory with an initial form (extra=1)
EntryForm_2Set = formset_factory(EntryForm_2,extra=1)
if request.method == 'POST':
    formset = EntryForm_2Set(request.POST,request.FILES)
    if formset.is_valid():            
        instances = []
        for f in formset.forms:
            # get the new applicant instance
            inst = f.save()
            instances.append(inst)
        for i in instances:
            # amend the applicant instance
            i.applicant = request.session['applicant']
            i.save()
        num_entered = formset.total_form_count()
        entry_url = reverse(...) # some reversal 
        return HttpResponseRedirect(entry_url)
else:
    formset = EntryForm_2Set()
template_dict['formset'] = formset
return render_to_response('submission-stage-two.html', template_dict, RequestContext(request)) 

模板代码:

<div id="entry_form">
<form method="post" enctype="multipart/form-data" action="/enter/2/" id="sheepItForm">

    % for form in formset.forms %            
            <fieldset id="sheepItForm_template">
                <a id="sheepItForm_remove_current">X</a>
                <div class="select"> form.select </div>
                <div class="text"> form.text </div>
                <div class="upload"> form.upload </div>
            </fieldset>
    % endfor %

  <div id="sheepItForm_controls">
    <div id="sheepItForm_add"><a ><strong>+</strong> Add Another</a></div>
  </div> 

  formset.management_form 
  <input type="submit" value="Proceed"> 

【讨论】:

【参考方案2】:

是的,首先使用表单集。然后初始表单上的字段将有一个前缀,您可以在克隆的表单上修改它以使其唯一。不要忘记更新表单集管理数据。

【讨论】:

嗨丹尼尔,感谢您的快速回复!我发现 SheepIt 确实为每个字段集设置了一个唯一的 ID,但我不太确定更新管理数据是什么意思,以及我将如何准确地分离出克隆?我正在用我清理的一些额外的 sn-ps 来更新这个问题。 (遗留代码...呃)

以上是关于提交时应该如何收集克隆的 Django 表单?的主要内容,如果未能解决你的问题,请参考以下文章

django 如何写表单提交

如何克隆 Django 模型实例对象并在 Django 表单上显示?

我的 django 表单如何获取当前用户名和电子邮件并将它们提交到另一个数据库表中?

无法提交克隆的表单

带有两个提交按钮的 Django 表单。 . .一个需要字段,一个不需要

django 编辑表单,数据怎么回显呀