Hassan Baig
Hassan Baig

Reputation: 15834

Fine tuning Django queryset retrieval

In a Django app of mine, I need to display, for a list of users (called user_ids), their:

username, avatar and score.

The username is retrieved from the User model, whereas avatar and score are present in the UserProfile model (that has a one-to-one field point to the User model, called user).

Currently my approach is to fetch the full objects (see below), even though I just need 3 attributes from the two models.

What's the most efficient way for me to just retrieve just the required fields, nothing else? Now I know i can do:

usernames = User.objects.filter(id__in=user_ids).values_list('username',flat=True)
scores_and_avatars = UserProfile.objects.filter(user_id__in=user_ids).values_list('score','avatar')

However, these give me separate querysets, so I can't iterate over them as a unified object_list and show each user's username, score and avatar in a Django template. So what would be the most efficient, light-weight way to retrieve and put this information together?


Currently, I'm doing the following to retrieve these three fields: queryset = User.objects.select_related('userprofile').filter(id__in=user_ids)

Upvotes: 0

Views: 92

Answers (1)

Dima  Kudosh
Dima Kudosh

Reputation: 7376

The most efficient way it's use values, your query will look like this:

usernames = User.objects.filter(id__in=user_ids).values('username', 'userprofile__score', 'userprofile__avatar')

This solution will return dictionary, but you can try to use only instead of values, it'll create django model object with specified fields, but if you will try to access not specified field it'll generate additional query.

usernames = User.objects.filter(id__in=user_ids).select_related('userprofile').only('username', 'userprofile__score', 'userprofile__avatar')

Upvotes: 1

Related Questions