I have the following three models:
models.py
class Exam(models.Model):
lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE, related_name="exams")
passing_grade = models.IntegerField(default=85)
must_pass = models.BooleanField(default=True)
to_next_lesson = models.BooleanField(default=True)
display_order = models.IntegerField(default=1)
class ExamQuestion(models.Model):
exam = models.ForeignKey(Exam, on_delete=models.CASCADE, related_name="questions")
text = models.CharField('Question', max_length=255)
class ExamAnswer(models.Model):
question = models.ForeignKey(ExamQuestion, on_delete=models.CASCADE, related_name="answers")
text = models.CharField('Answer', max_length=255)
is_correct = models.BooleanField('Correct answer', default=False)
The Form I require would render each question in an exam roughly something like this (sorry couldn't figure out to show rendered html in question:
<form>
<div>
"Quality" is one our core values<br />
<input type="radio"/> True <br />
<input type="radio"/> False
</div>
<div>
What should you do if you see an employee stealing?<br />
<input type="radio"/> Report it to your manager<br />
<input type="radio"/> Call the police<br />
<input type="radio"/> Confront the employee<br />
</div>
<div>
<input type="submit">
</div>
</form>
Ignoring the incomplete and possibly stupid HTML (shown bare bones here for the concept) How can I get the Django form language to output each individual question with multiple answers beneath it?
Note: The number of questions is variable, some exams might have 3 questions, others could have 5 or 6. The number of answers per question is also variable, some questions might have two answers - typically true or false, others could have four or five answers (right now there is only one correct answer for every question, so it is always using radio buttons)
The query in the view is sent the pk of the Exam, and pulls the appropriate text entries from the ExamQuestion and ExamAnswer tables.
I can put the questions and answers in any queryset, list, or dictionary required for the template, but I have not been able to figure out how to get them to display correctly in the template.
CodePudding user response:
In the Django forms you just:
STEALING= [
('Report it to your manage', 'Report it to your manage'),
('Call the police', 'Call the police'),
('Confront the employee', 'Confront the employee')
]
class UserForm(forms.Form):
your_form_field_name = forms.CharField(label='What should you do?', widget=forms.Select(choices=STEALING))
CodePudding user response:
I never found a way to do with this with a form in forms.py, so I simply created the needed HTML in the view(controller), passed it to the template and displayed it. The HTML required for each question was similar to what I showed in the question: a div showing a question, then in each div after that creating the radio buttons (adding the appropriate name="" attribute to create a radio group) and possible answers. Repeating this for as many questions and answers were retrieved from the database.
This worked perfectly, gave me exactly the results I needed.
As near as I can tell from my research, base Django Forms are generally designed for what most people consider a form: A series of fields that need to be filled in, (including multiple such forms in a formset) rather than more of a survey format where there is a question, then multiple answers to choose from.