Django formset只添加一个表单

时间:2014-02-22 20:19:23

标签: django django-forms django-templates django-views

好的,这是我第一次使用formset。我正在尝试创建一个表,我可以动态地添加行并填写每一行,然后提交并让Django将它们全部放在数据库中。每次我提交它时,只会添加第一个表单。

文件views.py:

@main_context_wrapper
def bacteriaForm2(request,context):
if not request.user.is_authenticated():
    #If user isn't authenticated, then just redirect to login
    return HttpResponseRedirect('/login/')
BacteriaFormSet = formset_factory(BacteriaForm)
if request.POST:
    bacteriaformset = BacteriaFormSet(request.POST, request.FILES)
    if bacteriaformset.is_valid():
        context["error"] = ""
        for form in bacteriaformset:
            form.save()
        return HttpResponseRedirect('/')
    else:
        context["error"] = "validation"
        context["bacteriaformset"] = BacteriaFormSet

    context.update(csrf(request))
    return render_to_response('bacteriaForm.html', context)

else:
    #The request was a GET, add the form to the context
    context["bacteriaformset"] = BacteriaFormSet()

#Add all siteInfo objects to allow for dynamic site info drop down menus
siteInfo = SiteInfo.objects.all()
context["siteInfo"] = siteInfo
return render(request, "bacteriaForm.html", context)

模板:

{% extends "inherited/main.html" %}

{% block content %}
<h1> Bacteria Entry Form </h1>

<form action='/bacteriaForm/' method="post">{% csrf_token %}
    {{bacteriaformset.management_form}}

    {% if error == "validation" %}
    <div class="alert alert-danger">
        <p>
            <strong>Error: </strong>Form not completed properly.
        </p>
    </div>
    {% endif %}

    <table id="id_forms_table">
        <tr>
            {% for field in bacteriaformset.forms.0 %}
                {% if not field.is_hidden %}
                     <th>{{ field.label }}</th>
                {% endif %}
            {% endfor %}
        </tr>
        {% for f in bacteriaformset.management_form %}
            {{ f }}
        {% endfor %}
        {% for f in bacteriaformset.forms %}
            <tr id="{{ f.prefix }}-row" class="dynamic-form">
            {% for field in f %}
                {% if not field.is_hidden %}
                     <td>
                     {{ field.errors }}
                     {{ field }}
                     </td>
                {% else %}
                     <td valign="bottom">{{ field }}</
                {% endif %}
            {% endfor %}
            <td{% if forloop.first %} class="hidden"{% endif %}>
                      <a id="remove-{{ form.prefix }}-row" href="javascript:void(0)"                           class="delete-row">delete</a>
            </td>
            </tr>
        {% endfor %}
        <tr>
            <td colspan="4"><a href="javascript:void(0)" class="add-row">add            property</a></td>
        </tr>

    </table>
    <div>
        <input type="submit" value="submit" />
    </div>
</form>

<script>
    $(function () {
        $('.add-row').click(function() {
            return addForm(this, 'form');
        });
        $('.delete-row').click(function() {
            return deleteForm(this, 'form');
        });
    });

    function updateElementIndex(el, prefix, ndx) {
        var id_regex = new RegExp('(' + prefix + '-\\d+)');
        var replacement = prefix + '-' + ndx;
        if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex,      replacement));
        if (el.id) el.id = el.id.replace(id_regex, replacement);
        if (el.name) el.name = el.name.replace(id_regex, replacement);
    }

    function addForm(btn, prefix) {
        var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
        var row = $('.dynamic-form:first').clone(true).get(0);
        $(row).removeAttr('id').insertAfter($('.dynamic-    form:last')).children('.hidden').removeClass('hidden');
        $(row).children().not(':last').children().each(function() {
            updateElementIndex(this, prefix, formCount);
            $(this).val('');
        });
        $(row).find('.delete-row').click(function() {
            deleteForm(this, prefix);
        });
        $('#id_' + prefix + '-TOTAL_FORMS').val(formCount + 1);
        return false;
    }

    function deleteForm(btn, prefix) {
        $(btn).parents('.dynamic-form').remove();
        var forms = $('.dynamic-form');
        $('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
        for (var i=0, formCount=forms.length; i<formCount; i++) {
            $(forms.get(i)).children().not(':last').children().each(function() {
                updateElementIndex(this, prefix, i);
            });
        }
        return false;
    }
    $("#id_date").datepicker();
</script>
{% endblock %}

File Models.py

class BacteriaEntry(models.Model):
"""
A bacteria entry contains information about a test set's
bacteria levels at a specific time. BacteriaEntry utilizes the
Djano model.
"""
siteNumber = models.IntegerField()
date = models.DateField()
sampleNumber = models.IntegerField(primary_key=True)
ecoliRawCount = models.IntegerField(null=True)
ecoli = models.DecimalField(decimal_places=10, max_digits=20, null=True)
ecoliException = models.IntegerField(null=True)
coliformRawCount = models.IntegerField(null=True)
coliform = models.DecimalField(decimal_places=10, max_digits=20, null=True)
coliformException = models.IntegerField(null=True)
comments = models.CharField(max_length=2000, null=True)

"""Returns the sample number of the Bacteria Entry"""
def __unicode__(self):
    return smart_unicode(self.sampleNumber)

以下是一些帖子数据

<QueryDict: {u'form-0-date': [u'02/24/2014'], u'form-0-comments': [u'65'], u'form- MAX_NUM_FORMS': [u'1000', u'1000'], u'form-0-coliformRawCount': [u'5'],
 u'form-0-coliform': [u'65'], u'form-0-ecoliException': [u'56'], u'form-TOTAL_FORMS':   [u'1', u'1'], u'form-0-sampleNumber': [u'1554'], u'form-0-ecoliRawC
 ount': [u'35'], u'form-0-coliformException': [u'56'], u'form-INITIAL_FORMS': [u'0',   u'0'], u'csrfmiddlewaretoken': [u'VSnaJCW6R9z8iEKib46cHuBJ6AKTPPUT'],
 u'form-0-ecoli': [u'51'], u'form-0-siteNumber': [u'100']}>

我不确定我的问题在哪里。我花了很多时间试图解决这个问题。我不确定有什么问题。

2 个答案:

答案 0 :(得分:0)

您没有在模板中的任何子表单中打印formset.non_form_errorsform.non_field_errors - 其中一个可能会导致验证失败。

我还应该指出,没有必要单独从formset实例化表单。创建一个单独的BacteriaForm实例并将其传递给模板是没有意义的,然后在post上验证它:毕竟这就是formset的用途。

答案 1 :(得分:0)

我对此有点困惑,不确定为什么你需要Form 一个FormSet,特别是因为FormSet包含相同的内容Forms和单独的Form ...

一样

但如果是这种情况,那么你应该在Form和/或FromSet上使用prefix

bacteriaForm = BacteriaForm(request.POST, prefix='the_one_bacteria')
bacteriaformset = BacteriaFormSet(request.POST, request.FILES, prefix='bacterias')

以及View中的else:部分。

原谅我的复数。