django-forms - 如何编写单元测试来检查 django 模型表单是否有效?
问题描述
我正在尝试测试模型表单是否有效。
在测试函数中,我创建了自定义表单中的两个模型。我添加数据以填写表单的必填字段。
当我运行测试并is_valid()
在表单上调用时,测试失败并且表单给出了我添加的选项的错误是not one of the available choices
. 这表明我错误地将Option
实例添加到表单或测试中。我不确定如何。
如何使模型表格对测试有效?
测试.py
def test_valid_data(self):
question_1 = Question(
question_text='What is the width of the telephone?',
date_published=timezone.now(),
collection=Collection.objects.create()
)
question_1.save()
option_1 = question_1.options.create(
question=question_1,
option_text='Five centimetres'
)
option_1.save()
data = {'question_text': question_1.question_text, 'selected_option': option_1.option_text,}
form = QuestionForm(data=data)
print(form)
self.assertTrue(form.is_valid())
表格.py
class QuestionForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(QuestionForm, self).__init__(*args, **kwargs)
self.fields['selected_option'] = forms.ChoiceField(
choices=[
(f'{option.pk}', f'{option}')
for option in Option.objects.filter(question_id=self.instance.pk)
],
widget=RadioSelect,
required=True,
error_messages={
'required': 'The question form lacks a selected_option'
}
)
class Meta:
model = Question
fields = ('question_text',)
labels = {
'question_text': ''
}
widgets = {
'question_text': forms.Textarea(attrs={'cols': '40', 'rows': '2'})
}
模型.py
class Question(models.Model):
question_text = models.CharField(max_length=400)
collection = models.ForeignKey(Collection, on_delete=models.PROTECT, default=None)
date_published = models.DateTimeField('date published')
def __str__(self) -> str:
return self.question_text
class Option(models.Model):
option_text = models.CharField(max_length=400)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
class Meta:
default_related_name = 'options'
def __str__(self) -> str:
return self.option_text
预期:is_valid()
->True
实际:is_valid()
->False
解决方案
该问题是由您在以下位置定义选择的方式引起的QuestionForm.__init__
:
choices=[
(f'{option.pk}', f'{option}')
for option in Option.objects.filter(question_id=self.instance.pk)
],
您已创建choices
基于与您启动的相关实例pk
的实例。Question
QuestionForm
在您的测试中(以及在管理员中),form
当Question
您通过输入
form = QuestionForm(data=data)
.
因此,查询Option.objects.filter(question_id=self.instance.pk)
返回None
,因为self.instance.pk
is None
。
因此,您在保存之前收到错误,QuestionForm
因为 choices = []
如果您按下“保存”按钮或执行form.save()
.
推荐阅读
- apache-spark - 根据 Dense Rank 减去两行的列值
- python - 如何使用 Numpy 高效地创建 ND 坐标数组?
- docker-compose - 找不到 docker ecs 命令
- azure - 自定义 MFA 中的消息
- python - 我如何在 django 中执行 'row in' 条件
- azure - Microsoft 标识平台客户端凭据流审核
- javascript - 在数组中找到某个键值对时,如何返回步数 [i]?
- java - 基于列值在java中对矩阵进行排序的最佳方法
- django - 序列化表示反向查找的布尔值的最佳方法
- java - 如何使用 Java API 仅将 Avro 文件中的非可选值插入 BigQuery 表