There is an inline formset that works perfectly well. It fails only in testing.
there is a model that connects two types of participants: senders and receivers.
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)
An inline formset is shown to senders, who choose how much to send to receivers:
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,
)
and
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()
so, when I try to test it, the line formset.save()
brings in error:
django.db.utils.IntegrityError: NOT NULL constraint failed:
riskpooling_sendreceive.receiver_id
as the receiver id was not set. Although, if I look at the content of the formset.forms which is returned, everything is in there. Again, in the real life everything is ok, and is properly saved. So only testing results in error. What I am doing wrong?
UPDATE:
I do not know if this important or not, but if I compare the output of self.request.POST in a normal flow (without testing) and with testing (the one that ends up with an error:
with testing:
<QueryDict: {'sender-0-sender': ['1'],
'sender-0-amount_sent': ['6'], 'sender-0-id': ['2'],
'sender-INITIAL_FORMS': ['1'], 'sender-TOTAL_FORMS': ['1']}>
no testing:
<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']}>
so apart from obvious difference in csrf token, everything looks the same.