This is how django annotate creates sql code: it performs all the necessary joins and then is grouped by all fields of the User, aggregating with the annotation function (account in your case). Thus, he joins users with all their favorite guides, and then with all the news, and then simply counts the number of lines created for each user.
If you can, you should use the raw querysets or extra query method. For instance:
User.objects.all().extra(select={ 'guide_likes': 'select count(*) from tbl_guide_likes where user_id=tbl_users.id', 'news_like': 'select count(*) from tbl_news_likes where user_id=tbl_users.id' }).\ values_list('first_name', 'last_name', 'guide_like','news_like')
For select_params flexibility, you can use the select_params parameter of the extra method to provide table names (which you can go through Model._meta ). By the way, this is a very inconvenient and hacker method. Sooner or later, your logic gets complicated, and then you have to remove it from python code in sql (stored functions / procedures) and raw queries.
source share