In Django, how can I filter based on all objects in many ways to many, and not in any?

I have a model like this:

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

I want to find all the tasks, all the prerequisites of which are completed. I tried:

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

This gets all the tasks for which any precondition is fulfilled. I thought maybe I need to use the annotation, but I don’t see how to apply the filter to the necessary requirements before performing the aggregation. For example, I can find the number of prerequisites for each task, for example:

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

But how can I comment on tasks with the number of prerequisites that have a status not equal to "C"?

+4
source share
1 answer

For your first question - "all tasks, all the prerequisites of which are completed":

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

This will also include tasks without any preconditions (since they do not have incomplete prerequisites). As a doctrine (using the definition of a model), the following passages:

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

This does not respond to how many unfinished preconditions each task has - what you may need for display, optimization, etc.

+4
source

All Articles