Django formset only adding one form

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-13 08:15:35

问题


OK, so this is my first time using formsets. I am trying to create a table that I can dynamically add rows to and fill out each row, then submit and have Django put them all in the database. Every time I submit it only adds the first form.

File 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)

Template:

{% 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)

Here is some post data

<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']}>

I'm not exactly sure where my problem is. I have spent a lot of time trying to figure this out. I am not sure what is wrong.


回答1:


You're not printing formset.non_form_errors, or form.non_field_errors in any of the child forms, in your template - there's probably something in one of those that is causing validation to fail.

I should also point out that there is no need to instantiate the form separately from the formset. It makes no sense to create a separate BacteriaForm instance and pass it to the template, then validate it on post: that's what the formset is for, after all.




回答2:


I'm a bit confused with this, not sure why you need both a Form and a FormSet, especially because the FormSet contains the same Forms as is the separate Form...

But if that is the case, then you should use prefix on the Form and/or on the FromSet:

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

and also in the else: part of the View.

Pardon my plural.



来源:https://stackoverflow.com/questions/21959989/django-formset-only-adding-one-form

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!