Based off this SO question about counting forgein keys, I have a problem. This is my models:
class Type(models.Model):
is_bulk = models.BooleanField()
class Component(models.Model):
parent = models.ForgeinKey(Type, related_name="components")
I want to write a queryset that has all types, except those that have is_bulk=True and have no components. If is_bulk=False, it should be included. If is_bulk=True and you have 1+ linked Components, then you’re included. If not, you’re excluded.
Based off the answer, I tried this queryset:
Type.objects.annotate(num_components=Count('components')).exclude(is_bulk=True, num_components=0)
But it returns no results.
However this implies that there should be results:
>>> [(x.is_bulk, x.num_components) for x in Type.objects.annotate(num_components=Count('components'))]
[(False, 0), (False, 0), (False, 0), (False, 0), (False, 0), (False, 0), (False, 0)]
All the Type objects have is_bulk=False and all of them have 0 Components. From reading the .exclude(…) documentation, it should be NOT(is_bulk=True AND num_components=0), which should be True for every Type. Right? (Have I made a misunderstanding here, if so, what’s the correct queryset)
If not, why is this queryset returning [], when it should return all of them? Is this a bug in Django 1.3?
I have fixed this by changing the queryset to:
That works, but I can’t see why my original one didn’t. Ah well.