Как отфильтровать данные из модели parant на основе наличия отношений с дочерней моделью

У меня есть эти модели


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()

как получить весь прогресс задачи, связанный с TaskType2 ,

TaskProgress.objects.filter(???)

Я не думаю, что то, о чем вы спрашиваете, возможно, если модели разработаны так, как описано. Внешний ключ base_task указывает конкретно на BaseTask. Даже если TaskType1 и TaskType2 наследуются от BaseTask, они не имеют никакого отношения в базе данных. Они только выглядят похожими.

Вариант 1: Посмотрите на Generic Relations в Django. В принципе, это позволяет вам иметь отношение ForeignKey с более чем одним типом модели. Однако я бы не рекомендовал это делать. Общие отношения - это сплошной беспорядок, если вы не знаете, что делаете.

Вариант 2: Переосмыслите свою схему. Возможно, вы можете переместить отношение к двум TaskTypes вместо этого и обращаться к ним через 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()

Таким образом вы создаете связь один-к-одному между TaskProgress и TaskType. Вы должны иметь возможность запрашивать то или другое, проверяя, существует ли связь, например, все экземпляры TaskProgress, имеющие связь с экземпляром TaskType1.

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

Я добавил дополнительное поле в класс BaseTask

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)

И фильтр будет выглядеть так

TaskProgress.objects.filter(base_task__task = "I")
Вернуться на верх