我正在尝试将
request
传递给单元测试中的 Django 表单。这是我的测试:
def test_AddPairedStudyForm(self):
self.client.force_login(self.user)
request = RequestFactory().get(reverse("researcher_ui:console"))
request.user = self.user
study_group = 'StudyGroup'
payload = {
"study_group": study_group,
"paired_studies": [self.study.id, self.study1.id],
'request': request
}
form = AddPairedStudyForm(data=payload)
self.assertTrue(form.is_valid())
这会生成以下形式的关键错误:
KeyError: 'request'
在表单本身内,此错误发生在
__init__
函数期间
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request")
super(AddPairedStudyForm, self).__init__(*args, **kwargs)
在 CBV 中,我使用
request
函数添加 get_form_kwargs
:
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs["request"] = self.request
return kwargs
如何将请求传递到单元测试中的表单?
避免表单出现一般问题的最佳方法是记住表单必须是“无状态”的。这在 django 中通常不是问题,但某些字段(例如具有关系的字段)会保留状态。如果您直接将 request 添加到表单,如您的示例所示:
class AddPairedStudyForm(forms.Form)
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request")
super().__init__(*args, **kwargs)
这会直接更改表单实例的状态。另一个建议是在表单initial
中添加 request。
...
form = AddPairedStudyForm(data=payload, initial={'request': request})
...
然后您可以在表单中随处的initial
中找到request。
class AddPairedStudyForm(forms.Form)
def clean(self, *args, **kwargs):
data = super().clean(*args, **kwargs)
...
request = self.initial.get('request')
# validate something accordingly request
...
return data
您可以看到,您不需要覆盖
__init__
,只需从**
kwargs中删除request。 有关初始的更多信息:https://docs.djangoproject.com/en/5.0/ref/forms/api/#initial-form-values