I am working with modelformset, and am a little stuck. I am passing, say 20 forms using modelformsetfactory. These forms are constructed and displayed in the page. When I return after the posting, I only want some of these forms to be validated and saved, not all of them, depending upon the value of a model field.
I figured I could use queryset in the request.POST to limit the forms that I want in my formset that are to be validated. But this is not working. Is there any way I can limit the number of forms?
For the queryset that limits model instances I tried
formset = PaymentOptionFormSet(request.POST, queryset=payment_option_posted_queryset)
I get the following error:
IndexError at /seller/seller_profile/
list index out of range
Traceback:
File "/home/shagun/work/tinla/django/core/handlers/base.py" in get_response
100. response = callback(request, *callback_args, **callback_kwargs)
File "/home/shagun/work/tinla/web/views/user_views.py" in seller_profile
164. formset = PaymentOptionFormSet(request.POST, queryset=payment_option_posted_queryset)
File "/home/shagun/work/tinla/orders/forms.py" in __init__
400. super(BasePaymentOptionFormSet, self).__init__(*args,**kwargs)
File "/home/shagun/work/tinla/django/forms/models.py" in __init__
423. super(BaseModelFormSet, self).__init__(**defaults)
File "/home/shagun/work/tinla/django/forms/formsets.py" in __init__
47. self._construct_forms()
File "/home/shagun/work/tinla/django/forms/formsets.py" in _construct_forms
97. self.forms.append(self._construct_form(i))
File "/home/shagun/work/tinla/django/forms/models.py" in _construct_form
447. kwargs['instance'] = self.get_queryset()[i]
File "/home/shagun/work/tinla/django/db/models/query.py" in __getitem__
172. return self._result_cache[k]
Exception Type: IndexError at /seller/seller_profile/
Exception Value: list index out of range
My code looks like this:
def seller_profile(request):
from accounts.models import PaymentOption, PaymentMode
payment_options = PaymentOption.objects.select_related('payment_mode').filter(payment_mode__client__id=1)
payment_option_queryset = PaymentOption.objects.filter(payment_mode__client__id='1')
payment_option_posted_queryset = PaymentOption.objects.filter(payment_mode__client__id='1', is_active='1')
if request.user.is_authenticated():
PaymentOptionFormSet = modelformset_factory(PaymentOption, formset = BasePaymentOptionFormSet, extra=0, fields = ("payment_delivery_address", "bank_branch", "bank_ac_name", "bank_ac_type", "bank_ac_no", "bank_address", "bank_ifsc", "is_active"))
user = request.user.get_profile()
if request.method == "POST":#If the form has been submitted
form1 = SellerProfileForm(request.POST, instance = user)
form2 = SellerNotificationForm(request.POST, instance = user)
formset = PaymentOptionFormSet(request.POST, queryset=PaymentOption.objects.all())
counting = 0
for form in formset.forms:
counting +=1
print "count = ",counting
print formset.is_valid()
if form1.is_valid() and form2.is_valid:
form1.save()
form2.save()
else:
my_acct_ctxt = getMyAccountContext(request)
return render_to_response('seller/seller_profile.html',
{
'form1': form1,
'form2': form2,
'formset': formset,
'error1': form1.errors,
'error2': form2.errors,
'errorformset': formset.errors,
'payment_options': payment_options,
'acc': my_acct_ctxt,
},
context_instance=RequestContext(request))
else: #If the form has not been submitted
form1 = SellerProfileForm(instance = user)
form2 = SellerNotificationForm(instance = user)
formset = PaymentOptionFormSet(queryset=payment_option_queryset)
counter = 0
my_acct_ctxt = getMyAccountContext(request)
return render_to_response('seller/seller_profile.html',
{
'form1': form1,
'form2': form2,
'formset': formset,
'payment_options': payment_options,
'acc':my_acct_ctxt,
},
context_instance=RequestContext(request))
If you’re needing to conditionally validate a formset, you can override the clean method of the formset. Here’s an example of how I’ve done this within admin on an inline formset, which you can probably change to suit your needs as the Formset classes are pretty homogenous.
I hope that helps you out!