With following model:
class Day(models.Model):
date = models.DateField(
unique=True,
null=False,
blank=False,
)
class Reservation(models.Model):
user = models.ForeignKey(
User,
null=False,
blank=False,
related_name='reservations',
verbose_name=_('Utilisateur'),
)
day = models.ForeignKey(
Day,
null=False,
blank=False,
related_name='reservations',
)
To get days ids where number of reservations is lower or equal 5 i do:
SELECT day_id
FROM meal_reservation
GROUP BY day_id
HAVING count(*) <= 5
But how to do it with Django ORM ?
Use Django's count() QuerySet method — simply append count() to the end of the appropriate QuerySet. Generate an aggregate over the QuerySet — Aggregation is when you "retrieve values that are derived by summarizing or aggregating a collection of objects." Ref: Django Aggregation Documentation.
The GROUP BY statement is used to combine rows with the same values, and it is mostly used with aggrege functions like COUNT(), AVG(), SUM(), etc. Whereas, the Django ORM is an abstraction layer that allows us to work with the database by translating the python code into a SQL statement.
Django's ORM is fantastic. It's slow because it chooses to be convenient but if it needs to be fast it's just a few slight API calls away. If you're curious, check out the code on Github.
Read the docs about the combination of using values+annotate, this is what you need:
from django.db.models import Count
Reservation.objects.values('day').annotate(cnt=Count('id')).filter(cnt__lte=5)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With