'Improve Django intermediary tables
I'm working on a Django app that contains the following structure:
There are Checklists consisting of one or more ChecklistItems. We want to assign however many checklists as we want to a Job, and fill these Job-Checklist's questions.
An example would be to create a Checklist containing ChecklistItems:
- "How are you?"
- "What is your name?"
So, each ChecklistItem is just a question in a checklist.
This means now we can use this Checklist that consists of 2 ChecklistItems in any job and fill it out after assigning it.
We create Job #1, and assign it this Checklist #1, create Job #2 and assign it Checklist #1 also. Same checklist to be answered in two different jobs. Whoever's working on that particular job will then fill the checklist out according to them.
The way we first approached this was with Job and Checklist being connected by a JobChecklist intermediary table, and JobChecklistItemAnswers being assigned to each answered checklist item (question).
class Checklist(models.Model):
"""A class to represent a checklist."""
name = models.CharField(_("name"), max_length=150)
class ChecklistItem(models.Model):
"""A class to represent an item of a checklist."""
checklist = models.ForeignKey(Checklist, on_delete=models.CASCADE)
question = models.CharField(_("question"), max_length=200)
class Job(models.Model):
"""A class to represent a job."""
checklists = models.ManyToManyField(Checklist, through="JobChecklist")
class JobChecklist(models.Model):
"""A class to represent the intermediary relation of a checklist belonging
to a job."""
job = models.ForeignKey(Job, on_delete=models.CASCADE)
checklist = models.ForeignKey(Checklist, on_delete=models.CASCADE)
class JobChecklistItemAnswer(models.Model):
"""A class to represent the relation of a checklist item's answer belonging
to a job's checklist."""
job_checklist = models.ForeignKey(JobChecklist, on_delete=models.CASCADE)
checklist_item = models.ForeignKey(ChecklistItem, on_delete=models.CASCADE)
answer = models.BooleanField(_("answer"), null=True)
def save(self, *args, **kwargs) -> None:
if (
self.checklist_item
not in self.job_checklist.checklist.checklistitem_set.all()
):
raise FieldError(
_(
"ChecklistItem #{} doesn't belong to {} checklist".format(
self.checklist_item.id, self.job_checklist.checklist
)
)
)
return super().save(*args, **kwargs)
As you can see from the JobChecklistItemAnswer relation, we had to monkey patch the save method to make sure the answer belongs to that particular checklist item (question).
We would like to solve this in Django ORM level. The problem appears to me as a common design pattern however I was unable to find any examples following this structure.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
