有一个内联的formset非常好用。它仅在测试中失败。
有一个连接两种类型参与者的模型:发件人和收件人。
models.py
:
class SendReceive(models.Model):
receiver =jmodels.ForeignKey(Player, related_name='receiver')
sender = models.ForeignKey(Player, related_name='sender')
amount_requested = models.IntegerField()
amount_sent = models.IntegerField(blank=True)
向发件人显示内联表单集,发件人选择向收件人发送多少内容:
forms.py
:
class SRForm(forms.ModelForm):
class Meta:
model = SendReceive
fields = ['amount_sent']
SRFormSet = inlineformset_factory(Player, SendReceive,
fk_name='sender',
can_delete=False,
extra=0,
form=SRForm,
)
和
的 views.py (CBV)
:
def post(self):
context = super().get_context_data()
formset = SRFormSet(self.request.POST, instance=self.player)
context['formset'] = formset
if not formset.is_valid():
return self.render_to_response(context)
formset.save()
return super().post()
所以,当我尝试测试时,行formset.save()
会导致错误:
django.db.utils.IntegrityError: NOT NULL constraint failed:
riskpooling_sendreceive.receiver_id
因为没有设置接收者ID。虽然,如果我查看返回的formset.forms的内容,一切都在那里。再一次,在现实生活中一切都很好,并得到妥善保存。所以只有测试结果是错误的。我做错了什么?
更新:
我不知道这是否重要,但如果我将self.request.POST的输出与正常流程(未经测试)和测试(最终出现错误的那个)进行比较:
测试:
<QueryDict: {'sender-0-sender': ['1'],
'sender-0-amount_sent': ['6'], 'sender-0-id': ['2'],
'sender-INITIAL_FORMS': ['1'], 'sender-TOTAL_FORMS': ['1']}>
没有测试:
<QueryDict: {'origin_url': [''], 'sender-INITIAL_FORMS': ['1', '1'],
'sender-MAX_NUM_FORMS': ['1000', '1000'], 'csrfmiddlewaretoken':
['KdpMPEJMOR4yHTMyO6KrS1bJE3eMfPBa'], 'sender-0-amount_sent': ['1'],
'sender-0-id': ['1'], 'sender-MIN_NUM_FORMS': ['0', '0'],
'sender-0-sender': ['62'], 'sender-TOTAL_FORMS': ['1', '1']}>
除了csrf令牌的明显区别外,一切看起来都一样。
答案 0 :(得分:1)
我发现了原因。
简而言之,当您通过FORMSET_NAME-0-id
时,您需要传递pk
实际记录(如果您不想创建新记录)。