3π
I think the most efficient way of calculating this is at write time. You should modify OrganizationalUnit like this:
class OrganizationalUnit(models.Model):
name = models.CharField(max_length=100)
parent = models.ForeignKey(
'self',
blank=True, null=True,
related_name='children',
)
checkout_number = models.IntegerField(default=0)
create the functions that will update the OrganizationalUnit and its parents at write time:
def pre_save_checkout(sender, instance, **kwargs):
if isinstance(instance,Checkout) and instance.id and instance.department:
substract_checkout(instance.department)
def post_save_checkout(sender, instance, **kwargs):
if isinstance(instance,Checkout) and instance.department:
add_checkout(instance.department)
def substract_checkout(organizational_unit):
organizational_unit.checkout_number-=1
organizational_unit.save()
if organizational_unit.parent:
substract_checkout(organizational_unit.parent)
def add_checkout(organizational_unit):
organizational_unit.checkout_number+=1
organizational_unit.save()
if organizational_unit.parent:
add_checkout(organizational_unit.parent)
now all you need is connect those functions to the pre_save, post_save and pre_delete signals:
from django.db.models.signals import post_save, pre_save, pre_delete
pre_save.connect(pre_save_checkout, Checkout)
pre_delete.connect(pre_save_checkout, Checkout)
post_save.connect(post_save_checkout, Checkout)
That should do itβ¦
3π
What you need is a recursive function that traverse OrganizationalUnit relation tree and gets number of related Checkouts for each OrganizationalUnit. So your code will look like this:
def count_checkouts(ou):
checkout_count = ou.checkouts.count()
for kid in ou.children.all():
checkout_count += count_checkouts(kid)
return checkout_count
Also note, that to get a number of related checkouts I use:
checkout_count = ou.checkouts.count()
insted of:
count = ou.checkouts.all().count()
My variant is more efficient (see http://docs.djangoproject.com/en/1.1/ref/models/querysets/#count).
- [Django]-How to do Delete confirmation for a table data with bootstrap Modal in Django?
- [Django]-How long does it take for a Djoser access token until expire?
- [Django]-Django 1.5 extend the default User model or substitute it
- [Django]-How should I upgrade from bradjasper's django-jsonfield to Django's built-in jsonfield?
- [Django]-Django: check a last character in string
0π
Iβm not sure how does SQL perform on this one but what you want to do is exactly what you explained.
Get all OU and itβs parents with While loop and then count Checkouts and sum them.
ORM brings you dynamic operations over SQL but kill performance:)