Joel G Mathew
Joel G Mathew

Reputation: 8061

Understanding django annotate

My models:

class Ward(models.Model):
    id = models.AutoField(primary_key=True, unique=True)
    clinic = models.ForeignKey(Clinic, on_delete=models.CASCADE)
    name = models.CharField(max_length=500, default='', blank=True)
    description = models.CharField(max_length=2000, default='', blank=True)
    bedcapacity = models.IntegerField(default=1)

class Bed(models.Model):
    id = models.AutoField(primary_key=True, unique=True)
    name = models.CharField(max_length=200, default='',
                            blank=True, unique=True)
    clinic = models.ForeignKey(Clinic, on_delete=models.CASCADE)
    ward = models.ForeignKey(Ward, on_delete=models.CASCADE)
    occupied = models.BooleanField(default=False)

I'm writing to convert the following pseudocode to django:

from django.db.models import F, Q, When
clinic = Clinic.objects.get(pk=10)
wards = Ward.objects.filter(clinic=clinic)
ward_set = []
for ward in wards:
    occupied = len(Bed.objects.filter(clinic = clinic, ward = ward, occupied = True))
    total = len(Bed.objects.filter(clinic = clinic, ward = ward))
    ward['occupied'] = occupied # The next two lines are pseudocode
    ward['total']=total
    ward_set.append(ward)
return render(request, 'file.html',
{
'wards': ward_set
})

I believe I should be using annotate, but I'm finding it difficult to understand annotate from the docs.

Upvotes: 0

Views: 62

Answers (1)

JPG
JPG

Reputation: 88499

What about this ?

from django.db.models import Q, Count

ward_set = Ward.objects.filter(clinic=10).annotate(
    occupied=Count('bed', filter=Q(bed__occupied=True)),
    total=Count('bed')

)

You could see some examples for conditional aggregation here

Upvotes: 2

Related Questions