Home > Mobile >  Django: Initialize a container model with child models when a new container is created - e.g. Todo l
Django: Initialize a container model with child models when a new container is created - e.g. Todo l

Time:02-17

I'm trying to create a todo list as part of an application that is used to prompt a user what they must complete before the application is assessed. To achieve this I have created a TaskList model and a Task model belonging to a TaskList.

When I create a new TaskList instance (on a new application) I want to prepopulate the list with some default Tasks that will always be present on every new application. I'm relatively new to Django and Python, so I'm just looking for a push in the right direction.

Is there some kind of Django model initialize function I can override on the TaskList to create these default tasks?

Edit: Django Model Fields

class AssessmentTaskList(models.Model):
    title = models.CharField(max_length=140)
    assessment = models.ForeignKey(Assessment, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)


class Task(models.Model):
    title = models.CharField(max_length=140)
    task_list = models.ForeignKey(AssessmentTaskList, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now_add=True)
    due_date = models.DateField(blank=True, null=True)
    completed = models.BooleanField(default=False)
    completed_date = models.DateField(blank=True, null=True)
    created_by = models.ForeignKey(User, limit_choices_to={
        'groups__name': 'Assessment Staff'}, on_delete=models.SET_NULL, null=True, related_name="applicant_task_created_by")
    system_created = models.BooleanField(default=False)
    note = models.TextField(blank=True, null=True)
    priority = models.PositiveIntegerField(blank=True, null=True)
    created_on = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)
    staff_task = models.BooleanField(default=False)

CodePudding user response:

You can either load the initial data along with migrations or provide separate fixtures with manage.py loaddata fixturefile.json:

https://docs.djangoproject.com/en/dev/howto/initial-data/

I'd suggest using the fixtures as long as you're just populating the initials and not changing the existing data in some way. In this case, the initial load would be an optional step and could be omitted in production/testing environments (migrations are always mandatory for execution).

EDIT: Actually what you need is to leverage the functionality of Django Signals (specifically django.db.models.signals.post_save model signal):

@receiver(post_save, sender=AssessmentTaskList)
def pre_populate_tasks(sender, instance: AssessmentTaskList, created: bool = False, **kwargs):
    if created:
        # put the pre-filled tasks here
        default_tasks = [Task(task_list=instance, ...)]
        Task.objects.bulk_create(default_tasks)
  • Related