Mam jeden formularz django, w którym pole wyboru jest zapełniane z bazy danych db.
class TestForm(forms.Form):
CLASS_CHOICE = []
classes = Class.objects.filter(std__gte=4)
for cls in classes:
CLASS_CHOICE.append((cls.code,
"{} - {}".format(cls.code,cls.std)))
name = forms.CharField()
class = forms.ChoiceField(choices = CLASS_CHOICE)
def _post_clean(self):
# some validation
pass
Podczas pisania testu jednostkowego jako:
class SampleTest(TestCase):
@classmethod
def setUpClass(cls):
super(SampleTest, cls).setUpClass()
cls.class = Class.objects.create(std=10,code="A")
def test_valid_form(self):
post_data = {"name":"testing",
"class":"A" }
f = TestForm(data=post_data)
self.assertTrue(f.is_valid())
Teraz problem polega na tym, że podczas uruchamiania testu aplikacja jest ładowana najpierw przed zainicjowaniem db, stąd setUpClass
dla testu jednostkowego nie wywoływany i CLASS_CHOICE
pozostaje pusty, a sprawdzanie poprawności formularza kończy się niepowodzeniem. Jak mogę tego uniknąć lub ponownie zainicjować pole wyboru po utworzeniu jednego wpisu Class
stół.
Odpowiedzi:
0 dla odpowiedzi № 1Sposób, w jaki konfigurujesz opcje wyboru, zostanie wypełniony tylko raz, gdy moduł zawierający twój kod zostanie wykonany po raz pierwszy. Jest to mniej niż idealne, ponieważ:
- dodane nowe klasy nie będą dostępne jako opcje wyboru
- baza danych może nie zostać podłączona, gdy moduł zostanie załadowany do pamięci, co spowoduje błędy w czasie wykonywania
Musisz to zrobić tak choices
jest budowany dynamicznie za każdym razem, gdy tworzony jest nowy formularz. Aby to zrobić, zrób choices
wywoływana funkcja zamiast listy:
def get_class_choices():
class_choice = []
classes = Class.objects.filter(std__gte=4)
for cls in classes:
class_choice.append((cls.code, "{} - {}".format(cls.code, cls.std)))
return class_choice
class TestForm(forms.Form):
name = forms.CharField()
class = forms.ChoiceField(choices=get_class_choices)
def _post_clean(self):
# some validation
pass