In Django, I've got a Checkout model, which is a ticket for somebody checking out equipment. I've also got an OrganizationalUnit model that the Checkout model relates to (via ForeignKey), as the person on the checkout belongs to an OrganizationalUnit on our campus.
The OrganizationalUnit has a self relation, so several OUs can be the children of a certain OU, and those children can have children, and so on. Here are the models, somewhat simplified.
class OrganizationalUnit(models.Model):
name = models.CharField(max_length=100)
parent = models.ForeignKey(
'self',
blank=True, null=True,
related_name='children',
)
class Checkout(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
department = models.ForeignKey(
OrganizationalUnit,
null=True,
blank=True,
related_name='checkouts',
)
I want to get a count of the Checkouts that are related to a certain OrganizationalUnit and all of its children. I know how to get the count of all the checkouts that are related to an OU.
ou = OrganizationalUnit.objects.get(pk=1)
count = ou.checkouts.all().count()
But how do I make that count reflect the checkouts of this OU's children and their children? Do I use some sort of iterative loop?
EDIT: I guess I still can't quite wrap my head around the while command to do this. The organizational units can go as deep as the user wants to nest them, but right now the most it goes in the DB is 5 deep. I've written this…
for kid in ou.children.all():
child_checkout_count += kid.checkouts.all().count()
for kid2 in kid.children.all():
child_checkout_count += kid2.checkouts.all().count()
for kid3 in kid2.children.all():
child_checkout_count += kid3.checkouts.all().count()
for kid4 in kid3.children.all():
child_checkout_count += kid4.checkouts.all().count()
for kid5 in kid4.children.all():
child_checkout_count += kid5.checkouts.all().count()
…which is total crap. And it takes a while to run because it pretty much traverses a major chunk of the database. Help! (I can't seem to think very well today.)