Django order by number of related objects in class Meta
In Django, i want to set the default model ordering to be by the number of related objects. In my case i would like to order the objects by the number of likes, where likes is a ManyToManyField of users that have liked the post:
class Post(models.Model):
likes = models.ManyToManyField(User)
class Meta:
ordering = [] # What can i put here?
The common solution seems to be django aggregation:
from django.db.models import Count
top_posts = Post.objects.annotate(num_likes=Count('likes')).order_by('-num_likes')
But this is called on the queryset, and doesn't seem like an option when defining the model.
Likely the best way is to work with a manager in this case:
class PostManager(models.Manager):
def get_queryset(self, *args, **kwargs):
return (
super()
.get_queryset(*args, **kwargs)
.alias(num_likes=Count('likes'))
.order_by('-num_likes')
)
class Post(models.Model):
likes = models.ManyToManyField(User)
objects = PostManager()