iva123
iva123

Reputation: 3515

Django model formset query generates extra object

I want to create a formset of confirmation models. I've succesfully created the formset however formset creates an extra confirmation object.

Here is my code:

VIEW

def render_fulfillment_modal(request,template='test.html'):
    ....
    formset = modelformset_factory(Confirmation)
    form = formset(queryset=Confirmation.objects.filter(customer_order__deal = deal))

   if request.method == 'POST':
      form = formset(request.POST, request.FILES)
      if form.is_valid():
         form.save()

TEMPLATE

<form method="post" action="{% url open_fullfill_modal deal.id %}">{% csrf_token %}
      {{ form.management_form }}                  
      {% for f in form %}       
      <tr>
      <td>{{f.fullfilled}}</td>                                 
      <td>
      <p class="name">{{f.instance|confirmation_user_info}}</p>                                  
      </td>                     
      <td><input type="text" class="input-small datepicker"></td>
      <td>{{f.tracking_code}}</td>
      </tr>
      {% endfor %}

     <div class="pull-right button-box"> 
        <button type="submit" class="btn btn-primary btn-large">Save Changes</button>
     </div>

I'm getting an extra form for unrelated object which is not in my queryset. I've tried this with another models and each time I'm getting an extra object. I suppose it's something with the formsets to handle data or something, I'm not sure. The problem occurs when I post this form. It gives me MultiValueDictKeyError which is :

"Key 'form-0-id' not found in <QueryDict: {u'form-MAX_NUM_FORMS': [u''], u'form-TOTAL_FORMS': [u'3'] ... 

Any ideas ?

Upvotes: 1

Views: 2158

Answers (2)

Salma Hassan
Salma Hassan

Reputation: 63

As you can see from the definition of modelformset_factory below (django docs) the extra parameter defaults to 1, which creates the extra object you mentioned.

modelformset_factory(model, form=ModelForm, formfield_callback=None, formset=BaseModelFormSet, extra=1, can_delete=False, can_order=False, max_num=None, fields=None, exclude=None, widgets=None, validate_max=False, localized_fields=None, labels=None, help_texts=None, error_messages=None, min_num=None, validate_min=False, field_classes=None, absolute_max=None, can_delete_extra=True)

So all you need to pass extra=0 to the formset:

formset = modelformset_factory(Confirmation, extra=0)

From Django docs: Limiting the number of editable objects

As with regular formsets, you can use the max_num and extra parameters to modelformset_factory() to limit the number of extra forms displayed.

Upvotes: 0

Marcos Venilton
Marcos Venilton

Reputation: 51

Just put a {{f.id}} before {{f.fullfilled}}

It's given a hidden form-id for all f, and pass it to QueryDict in request.Post

Upvotes: 5

Related Questions