【问题标题】:how to test inline formset如何测试内联表单集
【发布时间】:2023-03-19 02:35:02
【问题描述】:

有一个行之有效的内联表单集。它仅在测试中失败。

有一个模型可以连接两种类型的参与者:发送者和接收者。

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 令牌的明显差异之外,一切看起来都一样。

【问题讨论】:

  • 在您的表单中,唯一的字段是 amount_sent。因此,当您创建新对象时,您不会将接收者从模板发送到模板。这就是错误的原因。
  • 是的,你是对的,但是表单会更新记录,它不会创建记录。所以到那时接收器已经设置好了。
  • 嗯。将字段隐藏并添加到字段中怎么样?

标签: django inline-formset formsets otree


【解决方案1】:

我已经找到原因了。

简而言之,当您传递FORMSET_NAME-0-id 时,您需要将实际记录的pk 传递给那里(如果您不想创建新记录)。

【讨论】:

    猜你喜欢
    • 2012-03-20
    • 2017-04-12
    • 2019-05-15
    • 2011-07-25
    • 2018-02-09
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    相关资源
    最近更新 更多