测试InlineFormset清理方法

时间:2012-11-21 10:57:25

标签: python django django-forms inline-formset

我有一个Django项目,有2个模型,StructureBracket,Bracket有一个到结构的ForeignKey(即一对多,一个结构有很多Brackets)。我为管理站点创建了一个TabularInline,这样就可以在Structure上找到一个Brackets表。我添加了一个带有一些自定义clean方法的自定义formset来进行一些额外的验证,你不能让一个Bracket与同一个Structure上的另一个Bracket冲突等。

管理员看起来像这样:

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

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

BracketInlineFormset只有干净的方法:

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

一切正常,验证有效。

但是现在我想写一些unittest来测试我的复杂formset验证逻辑。

我首次尝试验证已知良好的值是:

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())

然而,这不起作用并引发异常:

======================================================================
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'

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

Django documentation(用于表单集验证)意味着可以执行此操作。

为什么这不起作用?如何测试内联formset的自定义clean()/验证?

1 个答案:

答案 0 :(得分:5)

您可以使用django.forms.models中的inlineformset_factory方法创建自定义内联formset。此方法根据传递给它的父类将fk值设置为formset。

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())

在使用工厂构建formset时注意formset=BracketInlineFormset参数。

参考:Django Docs