Search code examples
pythondjangoinline-formset

MultiValueDictKeyError while updating inline formsets


I'm having an issue with Django while updating inline formsets. I want to update a form and an inline formset, but it raises this error:

"MultiValueDictKeyError"

Exception Value: "u'clientphone_set-0-id'"

This is my view:

def edit_client(request, client_id):

    client_to_edit = Client.objects.get(id=client_id)
    form = ClientForm(instance=client_to_edit)
    phone_formset = ClientPhoneFormSet(instance=client_to_edit)

    if request.method == 'POST':
        form = ClientForm(request.POST, instance=client_to_edit)

        if form.is_valid():
            form_saved = form.save(commit=False)
            phone_formset = ClientPhoneFormSet(request.POST, request.FILES, instance=form_saved)

            if phone_formset.is_valid():
                form_saved.save()
                phone_formset.save()        
                return client(request)

    return render(request, 'WorkOrders/add_client.html', {'form' : form, 'phone_formset' : phone_formset})

And these are my forms

class ClientForm(forms.ModelForm):
    name = forms.CharField(max_length=128)
    rif = forms.CharField(max_length=10)
    address = forms.CharField(max_length=250)

    class Meta:
        model = Client
        fields = ('name','rif','address',)

ClientPhoneFormSet = inlineformset_factory(Client, ClientPhone, extra=1, fields=('phone_number',), can_delete=True)

And this is my template

<form class="form-horizontal" id="add_client" method="post" action=".">
    {% csrf_token %}
    {% for field in form.visible_fields %}
        <div class="form-group">
           <label for="{{ field.id }}" class="col-sm-2 control-label">{{ field.help_text }}</label>
           <div class="col-sm-10">
             {{ field.errors }}
             {{ field }}
           </div>
        </div>
    {% endfor %}
    <div class="form-group">
        <label for="{{ field.id }}" class="col-sm-2 control-label">Teléfono</label>
        <div class="col-sm-10">
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    {% for form in phone_formset.forms %}
                        <tr>
                            <td>
                                {% if form.instance.pk %}
                                    {{ form.DELETE }}
                                {% endif %}
                                {{ form.errors }}
                                {{ form.phone_number }}
                            </td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
{{ phone_formset.management_form }}
    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
            <button type="submit" class="btn btn-primary">Guardar</button>
            <a href="{% url 'index' %}" class="btn btn-primary">Volver</a>
        </div>
    </div>
</div>
</form> 

It opens the form with no problem, the error happens when I submit.

Thanks.


Solution

  • I fixed it by using phone_formset instead of phone_formset.forms, and added the {{ phone_field.id }}.

    Here is the result:

    <table border="0" cellpadding="0" cellspacing="0" width="100%">
        <tbody>
            {% for phone_field in phone_formset %}
            <tr>
               <td>
                  {% if phone_field.instance.pk %}
                    {{ phone_field.DELETE }}
                  {% endif %}
                  {{ phone_field.errors }}
                  {{ phone_field.id }}
                  {{ phone_field.phone_number }}
               </td>
            </tr>
            {% endfor %}
        </tbody>
    </table>