Django Model Field to Count Other Field

Question:

I have these models:

 
 ​class​ ​HatchingBatch​(​models​.​Model​): 
 ​    ​hatch_date​ ​=​ ​models​.​DateField​() 
 ​    ​incubator​ ​=​ ​models​.​CharField​(​max_length​=​32​) 
 ​    ​rhode_island_red​ ​=​ ​models​.​IntegerField​(​default​=​0​) 
 ​    ​barred_plymouth_rock​ ​=​ ​models​.​IntegerField​(​default​=​0​) 
 ​    ​black_australorp​ ​=​ ​models​.​IntegerField​(​default​=​0​) 
 ​     
 ​class​ ​Reservations​(​models​.​Model​): 
 ​    ​date​ ​=​ ​models​.​DateField​() 
 ​    ​hatch​ ​=​ ​models​.​ForeignKey​(​HatchingBatch​, ​related_name​=​"reservation"​, ​on_delete​=​models​.​CASCADE​) 
 ​    ​is_done​ ​=​ ​models​.​BooleanField​() 
 ​    ​is_delivery​ ​=​ ​models​.​BooleanField​() 
 ​    ​shipping_fee​ ​=​ ​models​.​IntegerField​() 
 ​    ​amount​ ​=​ ​models​.​IntegerField​()  
  
 ​
 ​class​ ​Stocks​(​models​.​Model​): 
 ​    ​hatch​ ​=​ ​models​.​OneToOneField​(​HatchingBatch​, ​on_delete​=​models​.​CASCADE​, ​related_name​=​"stock"​) 
 ​    

I want to add a field to the Stocks model that would be the number of the reserved chicks (easily done through ForeignKey) however, I also want to add a "sold" field that would correspond to the sum of the Reservations with "is_done" : True

Asked By: Dark Angel

||

Answers:

You can .annotate(…) [Django-doc] with:

from django.db.models import Count, Q

Stocks.objects.annotate(
    reservations=Count('​hatch​__reservation'),
    sold=Count('hatch__reservation', filter=Q(hatch__reservation__is_done=True))
)

The Stocks objects that arise from this QuerySet will have an extra attributes .reservations and .sold.

Answered By: Willem Van Onsem