With the following model, I would like to select root users having the most posts in validated state (in a single query or at least in an optimized way). In my case root user are not directly authors, I want to aggregate children user authors on root users.
class User(models.Model):
name = models.CharField(max_length=255)
# root users have no root
root = models.ForeignKey('User', blank=True, null=True)
class Post(models.Model):
STATE_CHOICES = (
(0, 'Writting'),
(1, 'Reviewing'),
(2, 'Validated'),
(3, 'Published'),
(4, 'Removed'),
)
state = models.IntegerField(choices=STATE_CHOICES, default=0)
# authors are no root user
author = models.ForeignKey('User')
# all validated but not published posts:
Post.objects.filter(state=2)
# all user having validated but not published posts:
User.objects.filter(post__state=2)
# same with number of posts
User.objects.filter(post__state=2).annotate(post_count=Count('post'))
# same ordered by number of posts
User.objects.filter(post__state=2).annotate(post_count=Count('post')).order_by('-post_count')
# same keeping only the top 10
User.objects.filter(post__state=2).annotate(post_count=Count('post')).order_by('-post_count')[:10]
# same aggregated for root users: NOT WORKING!
User.objects.filter(user__post__state=2).annotate(post_count=Count('post')).order_by('-post_count')[:10] # FieldError: Cannot resolve keyword 'user' into field.
User.objects.filter(root__post__state=2).annotate(post_count=Count('post')).order_by('-post_count')[:10] # no result
This issue may be related to the lack of backward relationship on a same model?
# works:
User.objects.filter(post__author=F('id'))
# not working:
User.objects.filter(user__root=F('id'))