2010-06-30 7 views
4

J'ai un modèle comme ceci:filtre ManyToManyField Django auto-récursif requête

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) 

Il fonctionne comme ceci, une activité peut être liée à elle-même et l'activité mère est appelée une « activité » et l'activité des enfants/les activités seront appelées 'Tâche/Tâches'

Comment filtrer le modèle pour obtenir toutes les 'Activités' et Comment filtrer le modèle pour obtenir toutes les 'Tâches'?

Merci pour toute l'aide.

Répondre

1

Ici, vous allez:

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) 

:)

Vous pouvez le faire avec de meilleures performances sans annotation, si vous utilisez __is_null=True, mais je ne me souviens pas ou rapide google est la syntaxe en ce moment.

+0

Doest travail tout à fait ce que je voulais. Les activités peuvent avoir 0 ou plusieurs «tâches» et les tâches peuvent également avoir 0 ou plusieurs «sous-tâches». Tout cela se passe dans la même table. Une activité est une activité uniquement si elle n'est pas un élément 'enfant' Une tâche est une tâche s'il s'agit d'un élément 'enfant' d'une activité. J'espère que j'ai du sens! Je sais que cela peut être fait, mais je ne sais pas comment. – ninja123

+0

réellement travaillé après avoir fait quelques tweeks ... Changé à: annotated_qs = Activity.objects.annotate (num_parent = Count ('activité')) = activités annotated_qs.filter (num_parent = 0) = tâches annotated_qs. filter (num_parent__gt = 0) – ninja123

1

Pour obtenir toutes les activités de haut niveau:

Activity.objects.filter(activity__isnull=True) 

Ceci est saisissant toutes les activités qui ont pas d'activité parent-dessus d'eux.

Pour obtenir toutes les tâches, sous-tâches, etc. (ceux qui ont une activité parent-dessus):

Activity.objects.filter(activity__isnull=False) 
Questions connexes