Как передать запрос форме в тесте

Я пытаюсь передать request в форму Django в unittest. Вот мой тест:

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

Как передать запрос форме в unittest?

Лучший способ избежать этой проблемы в общем случае с формой - помнить, что форма должна быть без состояния. Обычно это не является проблемой в django, но некоторые поля, например, поля с отношениями, сохраняют состояние. Если вы добавите request к форме напрямую, как в вашем примере:

class AddPairedStudyForm(forms.Form)

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("request")
        super().__init__(*args, **kwargs)

это напрямую изменяет состояние экземпляра формы. Еще одно предложение - добавить запрос к форме initials.

...
form = AddPairedStudyForm(data=payload, initials={'request': request})
...

Затем вы можете найти запрос в initials везде в форме.

class AddPairedStudyForm(forms.Form)

    def clean(self, *args, **kwargs):
        data = super().clean(*args, **kwargs)
        ...
        request = self.initials.get('request')
        # validate something accordingly request
        ...
        return data

Вы видите, что не нужно переопределять __init__ только для удаления запроса из **kwargs

Вернуться на верх