Husain Basrawala
Husain Basrawala

Reputation: 1751

Using aggregation in Django with

Following is my model:

class Story(models.Model):
    author = models.ForeignKey(User, related_name='author_id', default=1)
    source = models.ForeignKey(User, related_name='source_id', default=2)

User is the django provided model.

Now I need to find out number of articles authored and sourced by each user.

I thought of using story_set with user object:

res = User.objects.annotate(Count('story_set'))

However, there are two columns in story referencing User. Hence, Django won't know which one to use?

Can anyone help me on this?

Upvotes: 0

Views: 422

Answers (3)

U-DON
U-DON

Reputation: 2140

res = User.objects.annotate(num_authored=Count('author_id')).annotate(num_sourced=Count('source_id'))
res[0].num_authored
res[0].num_sourced

If you want both the number of authored and number of sourced articles in one query. You might want more appropriate related names, like "authored" and "sourced".

Upvotes: 0

second
second

Reputation: 28637

the reason django makes you specify a related_name is exactly for this reason. you want Count('author_id') instead of Count('story_set') (and you should probably give these better names, e.g. author_set)

Upvotes: 1

Chris Pratt
Chris Pratt

Reputation: 239250

story_set doesn't exist one way or another. That would've been the default related_name if you hadn't provided one. Since you did, you have to use those.

res = User.objects.annotate(Count('author_id'))

OR

res = User.objects.annotate(Count('source_id'))

So, that's how Django knows the difference.

FYI: if you had used the default (so you accessed stories via .story_set.all(), you don't use the "_set" part in queries. It would just be Count('story').

Upvotes: 1

Related Questions