Django Formset丢失管理表单数据
问题描述:
我正在尝试为formset编写单元测试,但在尝试实例化它时出现以下错误。Django Formset丢失管理表单数据
错误:
Traceback (most recent call last):
File "/home/jwelborn/Documents/projects/Bingo/bingo/cards/tests/test_forms.py", line 218, in test_formset_accepts_valid_data
self.assertTrue(formset.is_valid())
File "/home/jwelborn/Documents/projects/Bingo/bingoenv/lib/python3.6/site-packages/django/forms/formsets.py", line 321, in is_valid
self.errors
File "/home/jwelborn/Documents/projects/Bingo/bingoenv/lib/python3.6/site-packages/django/forms/formsets.py", line 295, in errors
self.full_clean()
File "/home/jwelborn/Documents/projects/Bingo/bingoenv/lib/python3.6/site-packages/django/forms/formsets.py", line 343, in full_clean
for i in range(0, self.total_form_count()):
File "/home/jwelborn/Documents/projects/Bingo/bingoenv/lib/python3.6/site-packages/django/forms/formsets.py", line 116, in total_form_count
return min(self.management_form.cleaned_data[TOTAL_FORM_COUNT], self.absolute_max)
File "/home/jwelborn/Documents/projects/Bingo/bingoenv/lib/python3.6/site-packages/django/utils/functional.py", line 35, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/home/jwelborn/Documents/projects/Bingo/bingoenv/lib/python3.6/site-packages/django/forms/formsets.py", line 98, in management_form
code='missing_management_form',
django.core.exceptions.ValidationError: ['ManagementForm data is missing or has been tampered with']
此错误说我失踪ManagmentForm数据,但我包括它在字典中,我传递给我的形式。我检查了不同的拼写,并改变了最小和最大数字,但无济于事。
forms.py:
class BingoSquareForm(ModelForm):
class Meta:
model = BingoCardSquare
exclude = ('created_date',)
BingoSquareFormset = inlineformset_factory(
BingoCard,
BingoCardSquare,
form=BingoSquareForm,
min_num=24,
validate_min=True,
max_num=24,
validate_max=True
)
tests.py
class BingoSquareFormsetTests(TestCase):
def setUp(self):
self.user = User.objects.get_or_create(
username='FormsetTestUser',
email='[email protected]'
)[0]
self.user.set_password('bingo')
self.user.save()
self.card = BingoCard.objects.get_or_create(
title='FormsetTest',
free_space='free_space',
creator=self.user,
)[0]
self.data = {
'form-TOTAL_FORMS': '24',
'form-INITIAL_FORMS': '0',
'form-MAX_NUM_FORMS': '24',
'form-MIN_NUM_FORMS': '24'
}
for i in range(24):
text_key = 'form-{}-text'.format(i)
text_value = 'square {}'.format(i)
self.data[text_key] = text_value
def test_formset_accepts_valid_data(self):
formset = BingoSquareFormset(self.data)
self.assertTrue(formset.is_valid())
有人能看到我在做什么错?
答
此错误是由于未对表单集的表单数据使用正确的前缀而导致的。 Django的inlineformset_factory
自动将formset前缀设置为子模型的ForeignKeyField中定义的related_name
。
models.py:
class BingoCardSquare(models.Model):
...
card = models.ForeignKey(
BingoCard,
related_name='squares',
on_delete=models.CASCADE,
)
...
在这种情况下,self.data
属性应该被设置为以下:
self.data = {
'squares-TOTAL_FORMS': '24',
'squares-INITIAL_FORMS': '0',
'squares-MAX_NUM_FORMS': '24',
'squares-MIN_NUM_FORMS': '24'
}
每个额外的形式将需要前缀相同的方式。希望这个答案能够帮助未来的遇难者。