1

I have the following inline formset:

CreateClientFormset = inlineformset_factory(
    Client,
    EventType,
    fields=(
        'name',
    ),
    extra=0,
    can_delete=True,
    min_num=1,
    validate_min=True,
    widgets={
        'name': forms.TextInput(attrs={
            'class':'form-control',
            'maxlength' : 50
        })
    })

And the following view:

def create_client(request):
    form = CreateClient()
    formset = CreateClientFormset(instance=Client())

    if request.method == 'POST':
        form = CreateClient(request.POST)

        if form.is_valid():
            client_saved = form.save(commit=False)
            client_formset = CreateClientFormset(request.POST, request.FILES, instance=client_saved)

            if client_formset.is_valid():
                client_saved.save()
                client_formset.save()

                return redirect(clients)
            else:
                print client_formset.errors
    else:
        print form.errors

    return render(request, 'create_client.html', {'form' : form, 'formset' : formset})

When I try to submit an empty value to the formset, it prints the error to the console but it doesn't do anything in the template.

This is my template:

{% for field in formset %}
{{ formset.management_form }}
    <tr>
        <td><label>{{ field.name.label }}</label></td>
            <td>
              {% if field.instance.pk %}{{ field.DELETE }}{% endif %}
              {{ field.name }}
              {{ formset.errors }}
              {{ field.id }}
              {% for hidden in formset.hidden_fields %}
                {{ hidden }}
              {% endfor %}
            </td>
    </tr>
{% endfor %}

{{ formset.errors }} displays [], even before the form submission.

What am I doing wrong? Thanks.

2
  • Where is the part of the view where you display the template? Commented Apr 29, 2016 at 19:45
  • See the edit @DanielRoseman, at the bottom of the "view" part. Commented Apr 29, 2016 at 19:52

2 Answers 2

2

I solved it like this:

if client_formset.is_valid():
    client_saved.save()
    client_formset.save()

    return redirect(clients)
else:
    print client_formset.errors
    return render(request, 'create_client.html', {'form' : form, 'formset' : formset, 'formset_errors' : client_formset.errors})

And in the template:

{% for field in formset %}
    <tr>
        <td><label>{{ field.name.label }}</label></td>
        <td>
            {% if field.instance.pk %}{{ field.DELETE }}{% endif %}
            {{ field.name }}
            {% if formset_errors %}
                {% for errors in formset_errors %}
                    {% for error in errors.values %}
                        {{ error }}
                    {% endfor %}
                {% endfor %}
            {% endif %}
            {{ field.id }}
            {% for hidden in formset.hidden_fields %}
                {{ hidden }}
            {% endfor %}
        </td>
    </tr>
{% endfor %}
Sign up to request clarification or add additional context in comments.

Comments

1

You render formset:

return render(request, 'create_client.html', {'form' : form, 'formset' : formset})

but the one loaded with your form data/errors is client_formset:

print client_formset.errors

The second one you need to pass to render since you are using {{ formset.errors }} in your template.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.