Django没有模型嵌套formset

时间:2015-02-20 11:31:51

标签: python django

我必须在Django中实现嵌套formset,但没有模型。问题是,我不知道如何正确地做到这一点。

我找到了嵌套formset的一些解决方案,但它们都使用数据库模型:

我需要没有模型的Django嵌套formset的原因是特定的工作流程,不能更改:

  1. 第一个用户填写没有模型的表单(我在这里使用嵌套的formset);
  2. 发布的数据被序列化为JSON并入选;
  3. 当另一个用户想要批准这些数据时,数据会被描述,反序列化并预先填充到使用数据库模型来保存数据的实际表单。
  4. 我能找到的唯一解决方案如下。该场景已经完成(但我有类似的情况)。第一个用户必须填写许多员工(姓氏)及其事件(日期和描述对)的数据。

    views.py:

    # -*- encoding: utf-8 -*-
    from django.shortcuts import render
    from django.forms.formsets import formset_factory
    from functools import partial, wraps
    from MultilevelFormset.forms import EmployeeForm
    
    def index(request):
        ffactory = formset_factory(wraps(EmployeeForm)(partial(EmployeeForm, maxsubforms=10)), extra=2)
        formset  = ffactory(request.POST or None, prefix='emp', auto_id=True)
    
        return render(request, 'MultilevelFormset/index.html', {'formset': formset})
    

    forms.py:

    # -*- encoding: utf-8 -*-
    from django import forms
    from django.forms.formsets import formset_factory
    
    class EmployeeForm(forms.Form):
        surname = forms.CharField()
    
        def __init__(self, *args, **kwargs):
            self.maxsubforms = kwargs.pop('maxsubforms')
            super(EmployeeForm, self).__init__(*args, **kwargs)
    
            # Each employee can have zero or more incidents
            max_incidents = self.maxsubforms
            for i in range(max_incidents):
                self.fields['date_%s' % i] = forms.DateField()
                self.fields['desc_%s' % i] = forms.CharField()
    

    的index.html

    <!DOCTYPE html>
    <html>
    <head>
        <title>Django multilevel formset example</title>
        <meta charset="utf-8" />
        <script src="{{ STATIC_URL }}js/jquery.js"></script>
        <script src="{{ STATIC_URL }}MultilevelFormset/js/jquery.formset.js"></script>
        <script>
            $(function() {
                $('.employee-container').formset({
                    prefix: '{{ formset.prefix }}'
                });
            });
        </script>
    </head>
    <body>
        {% load my_tags %}
    
        <form method="post" action="">
            {{ formset.management_form }}
    
            {% for form in formset %}
    
                {{ form.non_field_errors }}
                <div class="employee-container">
                    <h2>Employee</h2>
                    Surname: {{ form.surname.errors }}{{ form.surname }}
                    <h3>Employee incidents</h3>
                    <table>
                        <tr>
                            <td>Date</td>
                            <td>Description</td>
                        </tr>
    
                    {% for idx in form.maxsubforms|int2rangestr %}
                        {% with attr_date='date_'|add:idx attr_desc='desc_'|add:idx %}
                        <tr>
                            <td>{{ form|getFieldErrors:attr_date }} {{ form|getField:attr_date }}</td>
                            <td>{{ form|getFieldErrors:attr_desc }} {{ form|getField:attr_desc }}</td>
                        </tr>
                        {% endwith %}
                    {% endfor %}
                    </table>
                    <hr />
                </div>
            {% endfor %}
    
            <input type="submit" value="Submit" />
        </form>
    </body>
    </html>
    

    my_tags.py:

    from django import template
    register = template.Library()
    
    @register.filter(name='getField')
    def getField(form, fieldname):
        """Get form field"""
        return form[fieldname]
    
    @register.filter(name='getFieldErrors')
    def getFieldErrors(form, fieldname):
        """Get form field errors"""
        return form[fieldname].errors
    
    @register.filter(name='int2rangestr')
    def int2rangestr(intval):
        """e.g. return ['0', '1', '2', '3'] for intval=4"""
        lst = []
        for i in range(intval):
            lst.append(str(i))
    
        return lst
    

    首先,我尝试创建IncidentForm并将其分配给表单字段列表&#34;事件[]&#34;,但我无法以嵌套形式在 init 中创建正确的前缀。所以我尝试使用这种方法,其中嵌套表单字段就像名为date_0,desc0,date_1,desc_1,... date_n,desc_n的普通字段。 JavaScript将用于向用户隐藏字段。但这种做法看起来并不合适。

    我的问题是:在Django中没有模型的情况下实现嵌套formseth的正确方法是什么?

0 个答案:

没有答案