Home > Blockchain >  how to filter data from parant model based on if there relationship with child model
how to filter data from parant model based on if there relationship with child model

Time:12-22

I have these models


class Tree(models.Model):
    field = models.TextField()

class TaskProgress(models.Model):
    base_task = models.ForeignKey(BaseTask, on_delete=models.CASCADE)
    tree = models.ForeignKey(Tree, on_delete=models.CASCADE)

class BaseTask(models.Model):
   trees=models.ManyToManyField(Tree, through='TaskProgress')


class TaskType1(BaseTask):
   child1_field = models.TextField()

class TaskType2(BaseTask):
   child2_field = models.TextField()

how to get all taskprogress when related to TaskType2 ,

TaskProgress.objects.filter(???)

CodePudding user response:

I do not think what you are asking is possible, if the models are designed like described. The base_task ForeignKey is specifically pointing at a BaseTask. Even though TaskType1 and TaskType2 inherit from BaseTask, they have no relation in the database. They only look similar.

Option 1: Look into Generic Relations in Django. Basically it allows you to have a ForeignKey relation with more than one type of model. I would not recommend it though. Generic relations are a mess if you don't know want you are doing.

Option 2: Rethink your layout. Maybe you can move the relation to the two TaskTypes instead and adress them via related_name.

class TaskProgress(models.Model):
    # base_task = models.ForeignKey(BaseTask, on_delete=models.CASCADE)
    tree = models.ForeignKey(Tree, on_delete=models.CASCADE)

class TaskType1(BaseTask):
   task_progress = models.OneToOneField(TaskProgress, related_name='task_type_1'
   child1_field = models.TextField()

class TaskType2(BaseTask):
   task_progress = models.OneToOneField(TaskProgress, related_name='task_type_2'
   child2_field = models.TextField()

This way you create a one-to-one-relation between the TaskProgress and the TaskType. You should be able to query one or the other by checking whether a relation exists, e.g. all TaskProgress instances with a relation to a TaskType1 instance.

# Query all TaskProgress instances, that have a TaskType1
TaskProgress.objects.filter(task_type_1__isnull=False)

CodePudding user response:

I added extra field on BaseTask class

TASK_TYPE =[('I','Irrigation'),('C','Care'),('A','Assessment'),('O','Other')]

class BaseTask(models.Model):
    trees=models.ManyToManyField(Tree, through='TaskProgress')
    worker = models.ManyToManyField(User)
    task_type = models.CharField(max_length=1,choices=TASK_TYPE,null=True)

And the filter will be like this

TaskProgress.objects.filter(base_task__task = "I")
  • Related