Is there a way to use something like Django's annotate method, but for a collection of existing model instances instead of a queryset?
Say I have a model like this (all irrelevant details removed):
class Node(Model):
parent = ForeignKey('self', related_name='children')
If I were fetching some nodes and wanted the child count for each one, I could do this:
nodes = Node.objects.filter(some_filter=True).annotate(child_count=Count('children'))
for node in nodes:
print(node.child_count)
But what if I already have a collection of Node objects, instead of a queryset? The naïve way of doing this suffers from the N+1 query problem, which is unacceptable for performance:
for node in nodes:
print(node.children.count()) # executes a separate query for each instance
I essentially want the annotation equivalent of prefetch_related_objects. I'm picturing something like this:
nodes = list(Node.objects.filter(some_filter=True))
annotate_objects(nodes, child_count=Count('children'))
for node in nodes:
print(node.child_count)
Is there anything like this built into Django? Digging through the docs has not been fruitful for me.