Саморекурсивный фильтр Django для запроса ManyToManyField - PullRequest
4 голосов
/ 30 июня 2010

У меня есть такая модель:

class Activity(models.Model):  
    title = models.CharField(max_length=200)
    summary = models.TextField(null=True, blank=True)  
    tasks = models.ManyToManyField('self', symmetrical=False, null=True, blank=True)  

Это работает следующим образом: действие может быть связано с самим собой, а родительское действие называется «Действие», а дочернее действие / действия будут называться «Задача / Задачи»

Как отфильтровать модель, чтобы получить все «Действия» и Как отфильтровать модель, чтобы получить все «Задачи»?

Спасибо за помощь.

Ответы [ 2 ]

1 голос
/ 31 марта 2012

Чтобы получить все действия верхнего уровня:

Activity.objects.filter(activity__isnull=True)

Это захват всех действий, у которых нет родительской активности над ними.

Чтобы получить все задачи, подзадачи и т. Д.(те, у кого родительская активность выше):

Activity.objects.filter(activity__isnull=False)
1 голос
/ 30 июня 2010

Вот, пожалуйста:

from django.db.models import Count

annotated_qs = Activity.objects.annotate(num_tasks=Count(tasks))

activities = annotated_qs.objects.filter(num_tasks=0)
tasks = annotated_qs.objects.filter(num_tasks__gt=0)

:)

Вы можете сделать это с большей производительностью без аннотации, если вы используете __is_null=True, но я не могу вспомнить или быстро прогуглить его синтаксис прямо сейчас.

...