Reputation: 924
Using Django 2.1.3
Getting a strange error here; I have a form multiplechoicefield that draws its choices from the values existing in a model in the database.
class ChartForm(Form):
P_CHOICES = tuple((p["p"], p["p"]) for p in VAR.objects.all().values("p"))
p = MultipleChoiceField(widget=CheckboxSelectMultiple, choices=P_CHOICES, initial=P_CHOICES[0][1])
I am trying to run tests for a different app in the project. It throws the following error:
File "/code/pyyc/forms.py", line 31, in ChartForm
p = MultipleChoiceField(widget=CheckboxSelectMultiple, choices=P_CHOICES, initial=P_CHOICES[0][1])
IndexError: tuple index out of range
I assumed it was just because the model objects weren't loaded. So I added in the fixtures from the VAR app.
And yet, it still throws the error. Presumably, the Form is render before the test database is compiled ... ?
So I am now editing the Form so that P_CHOICES is done manually, but this is obviously not ideal for the test environment.
Anyone ever come across this? Is there a smart hack for this that doesn't involve commenting out lines in the Form every time you want to test?
Upvotes: 0
Views: 38
Reputation: 23044
Your presumption I think is correct. The class level attribute P_CHOICES
is created when Python first loads the ChartForm
class, before the test has actually started running. The fixtures are installed later as part of the test's setUpClass()
(called by the test framework) but by that point P_CHOICES
has already been defined and is empty.
You could try creating the MultipleChoiceField
without its choices
and initial
attributes, and then set those in the form's __init__
when the data is available. For example:
class ChartForm(Form):
p = MultipleChoiceField(widget=CheckboxSelectMultiple)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
p_choices = tuple((p["p"], p["p"]) for p in VAR.objects.all().values("p"))
# Now we have the data we can set the attributes
self.fields['p'].choices = p_choices
self.fields['p'].initial = p_choices[0][1]
Upvotes: 1