我有一个 Django 项目,有 2 个模型,一个
Structure
和 Bracket
,括号有一个结构的外键(即一对多,一个结构有多个括号)。我为管理站点创建了一个 TabularInline
,这样结构上就会有一个括号表。我添加了一个自定义表单集,其中包含一些自定义 clean
方法来进行一些额外的验证,您不能拥有与同一结构上的另一个括号冲突的括号等。
管理员看起来像这样:
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 …
一切正常,验证有效。
但是现在我想编写一些单元测试来测试我复杂的表单集验证逻辑。
我验证已知良好值的第一次尝试是:
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 文档(用于表单集验证)意味着可以做到这一点。
怎么这不起作用?如何测试内联表单集的自定义 clean()/验证?
您可以使用 django.forms.models 中的 inlineformset_factory 方法来创建自定义内联表单集。此方法根据传递给它的父类将 fk 值设置为表单集。
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=BracketInlineFormset
参数。
参考:Django 文档
对之前的回复稍作修改...
字段 = ['字段1', '字段2', ...]
BIFormset = inlineformset_factory(结构,支架,formset=BracketInlineFormset, 字段=字段 )
formset = BIFormset(数据, 前缀='表单', 实例=结构) self.assertTrue(formset.is_valid())