Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django formset unit test

I can't run a unit test with formset.

I try to do a test:

class NewClientTestCase(TestCase):          def setUp(self):         self.c = Client()      def test_0_create_individual_with_same_adress(self):                  post_data =  {             'ctype': User.CONTACT_INDIVIDUAL,             'username': 'dupond.f',                     'email': '[email protected]',              'password': 'pwd',              'password2': 'pwd',              'civility': User.CIVILITY_MISTER,              'first_name': 'François',              'last_name': 'DUPOND',              'phone': '+33 1 34 12 52 30',              'gsm': '+33 6 34 12 52 30',              'fax': '+33 1 34 12 52 30',              'form-0-address1': '33 avenue Gambetta',              'form-0-address2': 'apt 50',              'form-0-zip_code': '75020',              'form-0-city': 'Paris',              'form-0-country': 'FRA',              'same_for_billing': True,                     }                  response = self.c.post(reverse('client:full_account'), post_data, follow=True)             self.assertRedirects(response, '%s?created=1' % reverse('client:dashboard')) 

and I have this error:

ValidationError: [u'ManagementForm data is missing or has been tampered with']

My view :

def full_account(request, url_redirect=''):         from forms import NewUserFullForm,  AddressForm,  BaseArticleFormSet          fields_required = []     fields_notrequired = []          AddressFormSet = formset_factory(AddressForm, extra=2,  formset=BaseArticleFormSet)          if request.method == 'POST':                 form = NewUserFullForm(request.POST)                 objforms = AddressFormSet(request.POST)                             if objforms.is_valid() and form.is_valid():                         user = form.save()                         address = objforms.forms[0].save()                           if url_redirect=='':                 url_redirect = '%s?created=1' % reverse('client:dashboard')                 logon(request, form.instance)                         return HttpResponseRedirect(url_redirect)     else:         form = NewUserFullForm()         objforms = AddressFormSet()             return direct_to_template(request, 'clients/full_account.html', {         'form':form,         'formset': objforms,          'tld_fr':False,      }) 

and my form file :

class BaseArticleFormSet(BaseFormSet):      def clean(self):                          msg_err = _('Ce champ est obligatoire.')         non_errors = True                  if 'same_for_billing' in self.data and self.data['same_for_billing'] == 'on':             same_for_billing = True         else:                         same_for_billing = False                  for i in [0, 1]:                          form = self.forms[i]                                     for field in form.fields:                                                 name_field = 'form-%d-%s' % (i, field )                 value_field = self.data[name_field].strip()                                                  if i == 0 and self.forms[0].fields[field].required and value_field =='':                                         form.errors[field] = msg_err                                         non_errors = False                                      elif i == 1 and not same_for_billing and self.forms[1].fields[field].required and value_field =='':                     form.errors[field] = msg_err                                         non_errors = False                  return non_errors  class AddressForm(forms.ModelForm):      class Meta:         model = Address      address1 = forms.CharField()     address2 = forms.CharField(required=False)     zip_code = forms.CharField()     city = forms.CharField()     country = forms.ChoiceField(choices=CountryField.COUNTRIES,  initial='FRA') 
like image 359
Py. Avatar asked Oct 27 '09 13:10

Py.


2 Answers

In particular, I've found that the ManagmentForm validator is looking for the following items to be POSTed:

form_data = {             'form-TOTAL_FORMS': 1,              'form-INITIAL_FORMS': 0  } 
like image 161
southgate Avatar answered Sep 27 '22 19:09

southgate


Every Django formset comes with a management form that needs to be included in the post. The official docs explain it pretty well. To use it within your unit test, you either need to write it out yourself. (The link I provided shows an example), or call formset.management_form which outputs the data.

like image 25
Bartek Avatar answered Sep 27 '22 18:09

Bartek