title: Django formset - how to update an object?
body: <p>How can I update an object from a formset using <code>request.POST</code>?</p>
  
  <p>Here is my code and my problem is that this always creates a new <code>PhoneNumber</code> object. But I want to update the old <code>PhoneNumber</code> object.</p>
  
  <pre><code>def contact_detail(request, contact_id):
      contact = get_object_or_404(Contact, pk=contact_id)
      phone_number_list = PhoneNumber.objects.filter(contact=contact_id)
  
      if request.method == 'POST':
          cform = ContactForm(request.POST, instance=contact)
          #the next line is probably wrong!
          phonenumberformset = PhoneNumberFormSet(request.POST, queryset=phone_number_list)
  
          if cform.is_valid() and phonenumberformset.is_valid():
              phonenumber_instances = phonenumberformset.save(commit=False)
              for phonenumber in phonenumber_instances:
                  phonenumber.contact = contact
                  phonenumber.save()
  
              request.user.message_set.create(message='The contact "%s" was chanced successfully.' % contact.__str__())
              return HttpResponseRedirect("/crm/contacts/?oby=1")
      else:
          cform = ContactForm(instance=contact)
          phonenumberformset = PhoneNumberFormSet(queryset=phone_number_list)
  
      return render_to_response(
          'crm/contact_detail.html',
          {'cform': cform, 'phonenumberformset': phonenumberformset,},
          context_instance = RequestContext(request),
      )
  </code></pre>
  
  <p>Edit: I create three PhoneNumberForms:</p>
  
  <pre><code>PhoneNumberFormSet = modelformset_factory(PhoneNumber, max_num=3, extra=3, exclude=('contact',))
  </code></pre>
  
  <p>Edit: The solution using inlineformset_factory:</p>
  
  <pre><code>@login_required
  def contact_detail(request, contact_id):
      contact = get_object_or_404(Contact, pk=contact_id)
      PhoneNumberInlineFormSet = inlineformset_factory(Contact, PhoneNumber, max_num=3)
  
      if request.method == 'POST':
          cform = ContactForm(request.POST, instance=contact)
          classificationformset = ClassificationInlineFormSet(request.POST, request.FILES, instance=contact)
          addressformset = AddressInlineFormSet(request.POST, request.FILES, instance=contact)
          phonenumberformset = PhoneNumberInlineFormSet(request.POST, request.FILES, instance=contact)
          if cform.is_valid() and phonenumberformset.is_valid():
              contact = cform.save()
              phonenumberformset.save()
  
              request.user.message_set.create(message='The contact "%s" was chanced successfully.' % contact.__str__())
              return HttpResponseRedirect("/crm/contacts/?oby=1")
      else:
          cform = ContactForm(instance=contact)
          phonenumberformset = PhoneNumberInlineFormSet(instance=contact)
  
  return render_to_response(
          'crm/contact_detail.html',
          {'cform': cform, 'phonenumberformset': phonenumberformset,},
          context_instance = RequestContext(request),)
  </code></pre>
  
  <p>This approach even adds a delete checkbox to each inline form. Easy and great.</p>