Django QA forms with sections

I am stuck and I try to explain to you what I am trying to accomplish.

I am creating an application to create, organize and respond to operational checklists.

I have a structure like: checklist -> section -> question -> answer type -> answer

Each question can have a different and configurable answer type, for example:

  • the fire extinguisher is in the correct place: Yes / No
  • what state is the main switch in: On / Off

I have create models/views/forms for managing and sorting "checklist -> section -> question -> answer type -> answer" and it works.

Here is the model.py

class Checklist(models.Model):
    class Meta:
        verbose_name = "Checklist"
        verbose_name_plural = "Checklists"

    name = models.CharField(max_length=64)
    Description = models.CharField(max_length=64)

    def __str__(self):
        return self.name


class Section(OrderedModel):
    class Meta:
        ordering = ('order',)
        verbose_name = “Section”
        verbose_name_plural = “Sections”
    name = models.CharField(max_length=64)
    description = models.CharField(max_length=64)
    checklist = models.ForeignKey(
        Checklist, on_delete=models.CASCADE, blank=True, null=True, default=None, related_name=‘section_rel')

    def __str__(self):
        if self.checklist:
            return self.checklist.name + " - " + self.name
        else:
            return self.name

class AnswersValue(models.Model):
    class Meta:
        verbose_name = "Answers Value"
        verbose_name_plural = "Answers Values”
    name = models.CharField(max_length=16, unique=True)
    value = models.CharField(max_length=16, unique=True)

    def __str__(self):
        return self.name


class AnswerType(models.Model):
    class Meta:
        verbose_name = "Answer Type"
        verbose_name_plural = "Answer Types”
    name = models.CharField(max_length=24, unique=True)
    values = models.ManyToManyField(AnswersValue)

    def __str__(self):
        return self.name


class Question(OrderedModel):
    class Meta:
        ordering = ('order',)
        verbose_name = “Question”
        verbose_name_plural = "Questions”
    text = models.CharField(max_length=64)
    description = models.CharField(
        max_length=64, null=True, blank=True)
    section = models.ForeignKey(
        Section, on_delete=models.CASCADE, related_name=‘question_rel')

    answer_type = models.ForeignKey(
        AnswerType, on_delete=models.CASCADE)

Then I created a model to collect the checklist answers:

class FilledModule(models.Model):
    class Meta:
        verbose_name = "Filled Module"
        verbose_name_plural = "Filled Modules”

    name = models.CharField(max_length=64)
    checklist = models.ForeignKey(
        Checklist, on_delete=models.CASCADE)

    def __str__(self):
        if self.checklist:
            return self.name + " - " + self.checklist.name
        else:
            return self.name


class Response(models.Model):
    class Meta:
        verbose_name = "Response Module"
        verbose_name_plural = "Response Modules”

    module = models.ForeignKey(
        FilledModule, on_delete=models.CASCADE)

    question = models.ForeignKey(
        Question, on_delete=models.CASCADE)
    answer = models.ForeignKey(
        AnswersValue, on_delete=models.CASCADE)

    def __str__(self):
        if self.module:
            return "[id.module: " + str(self.module.id) + "] - " + self.module.name + " - " + self.module.checklist.name + " - " + self.question.text
        else:
            return self.question.text

I have created a view from where for each checklist id I get the sections and related questions of each. but, here comes my problem ...

How can I create a form containing the various answers that can be selected for each question in each section?

For now i create two list one contain sections objects and a nested list containing question_objects of each sections but I'm not sure if it really serves the purpose...

def fill_checklist(request, id_checklist, template_name='checklist/compile_checklist.html'):
    list_question = []
    list_sections = []
    checklist = Checklist.objects.get(pk=id_checklist)
    sections = checklist.section_rel.all()

    for section in sections:
        list_sections.append(section)
        section_questions = []
        for question in section.question_rel.all():
            section_questions.append(question)
        list_question.append(section_questions)

What I need now is a form structured like:

_____________________________
CHECKLIST TITLE & DESCRIPTION
COMPILED BY: <name>

SECTION TITLE 1:
 QUESTION id1: <RESPONSE based on ANSWER TYPE>
 QUESTION id3: <RESPONSE based on ANSWER TYPE>
SECTION TILE 2:
 QUESTION id8: <RESPONSE based on ANSWER TYPE>
[...]

<SUBMIT>
_____________________________

... that create a FilledModule that save 'checklist_id' and 'name' and then store each answers on model Response with 'fileldmodule_id', 'question_id' and 'response_id'.

I am in serious difficulty in understanding how to structure the form and the linked template to achieve this, any help to take the right road is really appreciated.

I have the feeling of thinking in a difficult way about a simple thing but I can't get to the result :-|

Thank you

(I translated the name of the variables IT2EN on the fly and I hope I have not made mistakes)

Back to Top