J'ai un formulaire django où un champ de choix est rempli à partir de 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
Lors de l'écriture de son test unitaire comme:
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())
Maintenant, le problème est que lors de l'exécution du test, l'application est chargée en premier avant d'initialiser db d'où la setUpClass
pour le test unitaire ne se fait pas appeler et CLASS_CHOICE
reste vide et la validation du formulaire échoue. Comment puis-je éviter cela ou réinitialiser le champ de choix après avoir créé une entrée dans Class
table.
Réponses:
0 pour la réponse № 1La façon dont vous avez configuré les choix de classe ne sera renseignée qu'une seule fois, lorsque le module contenant votre code sera exécuté pour la première fois. C'est loin d'être idéal car:
- si de nouvelles classes sont ajoutées, elles ne seront pas disponibles comme options de choix
- la base de données peut ne pas être connectée lorsque ce module est chargé en mémoire, provoquant des erreurs d'exécution
Vous devez faire en sorte que choices
est construit dynamiquement chaque fois qu'un nouveau formulaire est créé. Pour ce faire, choices
une fonction appelable plutôt qu'une liste:
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