Unable to set form choices from view Django

I learned how to do this from Django Form ChoiceField set choices in View in Form initial

However it doesn't seem to work correctly, choices are not given

view:

form_class = AskMCQuestionForm()
mc_choices = []
if question.One:
    mc_choices.append(tuple((1, question.One)))
if question.Two:
    mc_choices.append(tuple((2, question.Two)))
if question.Three:
    mc_choices.append(tuple((3, question.Three)))
if question.Four:
    mc_choices.append(tuple((4, question.Four)))
if question.Five:
    mc_choices.append(tuple((5, question.Five)))
mc_choices = tuple(mc_choices)
print(mc_choices)
form_class.fields['user_answer'].choices = mc_choices
form_class.fields['assignment'].initial = assignment
form_class.fields['exam'].initial = question.exam
form_class.fields['correct_answer'].initial = question.correct_answer
form_class.fields['text'].initial = question.text
print("About to render page for MC question")
return render(request, 'Exam/ask_question.html', {'question': question, 'form': form_class})

form:

class AskMCQuestionForm(forms.ModelForm):
    class Meta:
        model = MC_Question
        fields = ('text', 'user_answer', 'assignment', 'correct_answer', 'exam',)
        widgets = {
            'text': forms.TextInput(attrs={'class': 'form-control', 'readonly': True}),
            'user_answer': forms.Select(attrs={'class': 'form-control'}),
            'assignment': forms.Select(attrs={'class': 'form-control'}),
            'correct_answer': forms.HiddenInput(),
            'exam': forms.HiddenInput(),

        }

model:

class MC_Question(models.Model):
    One = models.CharField(max_length=200)
    Two = models.CharField(max_length=200)
    Three = models.CharField(max_length=200, blank=True, null=True)
    Four = models.CharField(max_length=200, blank=True, null=True)
    Five = models.CharField(max_length=200, blank=True, null=True)

    class Answers(models.IntegerChoices):
        one = 1
        two = 2
        three = 3
        four = 4
        five = 5
    text = models.CharField(max_length=200)
    correct_answer = models.IntegerField(choices=Answers.choices, blank=True, null=True)
    user_answer = models.CharField(max_length=200)
    exam = models.ForeignKey(Test, on_delete=models.CASCADE)
    assignment = models.ForeignKey(Assignment, on_delete=models.CASCADE, blank=True, null=True)

question is an object of MC_Question, the same as what the form is creating. Apologies if I have left out an important detail, it's been several years since I posted on stackoverflow


Solution 1:

By default the model form creates a TextInput to work with the user_answer field (is a models.CharField without choices), and the TextInput field does not know what to do with the choices argument. You can try to assing the choices directly to the widget:

form_class.fields['user_answer'].widget.choices = mc_choices

Or add a custom field to your model form:

class AskMCQuestionForm(forms.ModelForm):
    user_answer = forms.ChoiceField(...)