2009-10-04 7 views
4

J'ai un modèle comme celui-ci:Dans Django, comment filtrer en fonction de toutes les entités dans une relation plusieurs-à-plusieurs au lieu de toutes?

class Task(models.model): 
    TASK_STATUS_CHOICES = (
     (u"P", u'Pending'), 
     (u"A", u'Assigned'), 
     (u"C", u'Complete'), 
     (u"F", u'Failed') 
    ) 
    status = models.CharField(max_length=2, choices=TASK_STATUS_CHOICES) 
    prerequisites = models.ManyToManyField('self', symmetrical=False, related_name="dependents") 

Je veux trouver toutes les tâches dont les conditions préalables sont tous complet. J'ai essayé:

Task.objects.filter(prerequisites__status=u"C") 

Cela obtient toutes les tâches pour lesquelles aucune condition préalable est terminée. J'ai pensé que je devais peut-être utiliser une annotation, mais je ne vois pas comment appliquer un filtre sur les tâches prérequises avant d'effectuer une agrégation. Par exemple, je peux trouver le nombre de pré-requis de chaque tâche comme ceci:

Task.objects.annotate(prereq_count=Count('prerequisites')) 

Mais comment puis-je annoter des tâches avec le nombre de leurs conditions qui ont un statut différent de « C »?

Répondre

4

Pour votre première question - « toutes les tâches dont les conditions préalables sont tous complets »:

>>> Task.objects.exclude(prerequisites__status__in=['A','P','F']) 

Cela comprendra également des tâches sans conditions préalables (car ils ont aucune condition préalable incomplètes). En tant que doctest (en utilisant la définition de votre modèle), les passages suivants:

>>> a = Task.objects.create(status='C') 
>>> b = Task.objects.create(status='A') 
>>> b.prerequisites.add(a) 
>>> c = Task.objects.create(status='P') 
>>> c.prerequisites.add(b) 
>>> prerequisites_complete = Task.objects.exclude(prerequisites__status__in=['A','P','F']) 
>>> set([t.id for t in prerequisites_complete]) == set([a.id, b.id]) 
True 

Cela ne répond pas combien de conditions préalables incomplètes chaque tâche a - que vous pourriez avoir besoin pour l'affichage, l'optimisation, etc.

Questions connexes