Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing InlineFormset clean methods

I have a Django project, with 2 models, a Structure and Bracket, the Bracket has a ForeignKey to a Structure (i.e. one-to-many, one Structure has many Brackets). I created a TabularInline for the admin site, so that there would be a table of Brackets on the Structure. I added a custom formset with some a custom clean method to do some extra validation, you can't have a Bracket that conflicts with another Bracket on the same Structure etc.

The admin looks like this:

class BracketInline(admin.TabularInline):
    model = Bracket
    formset = BracketInlineFormset

class StructureAdmin(admin.ModelAdmin):
    inlines = [
        BracketInline
    ]
admin.site.register(Structure, StructureAdmin)

The BracketInlineFormset just has the clean method:

class BracketInlineFormset(forms.models.BaseInlineFormSet):
    def clean(self):
        … my clean code here …

That all works, and the validation works.

However now I want to write some unittest to test my complex formset validation logic.

My first attempt to validate known-good values is:

data = {'form-TOTAL_FORMS': '1', 'form-INITIAL_FORMS': '0', 'form-MAX_NUM_FORMS': '', 'form-0-field1':'good-value', … }
formset = BracketInlineFormset(data)
self.assertTrue(formset.is_valid())

However that doesn't work and raises the exception:

======================================================================
ERROR: testValid (appname.tests.StructureTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/paht/to/project/tests.py", line 494, in testValid
    formset = BracketInlineFormset(data)
  File "/path/to/django/forms/models.py", line 672, in __init__
    self.instance = self.fk.rel.to()
AttributeError: 'BracketInlineFormset' object has no attribute 'fk'

----------------------------------------------------------------------

The Django documentation (for formset validation) implies one can do this.

How come this isn't working? How do I test the custom clean()/validation for my inline formset?

like image 298
Amandasaurus Avatar asked Nov 21 '12 10:11

Amandasaurus


1 Answers

You can use the inlineformset_factory method from django.forms.models to create a custom inline formset. This method sets the fk value to your formset based on the parent class passed on to it.

structure = StructureFactory() #foreign key
data = {'form-TOTAL_FORMS': '1', 'form-INITIAL_FORMS': '0', 'form-MAX_NUM_FORMS': '', 'form-0-field1':'good-value', … }
BIFormset = inlineformset_factory(Structure, Bracket, formset=BracketInlineFormset)
formset = BIFormset(data, prefix='form', instance=structure) 
self.assertTrue(formset.is_valid())

Note the formset=BracketInlineFormset parameter while constructing the formset with the factory.

Reference: Django Docs

like image 60
Suganthi Avatar answered Oct 06 '22 20:10

Suganthi