Извлечение определенных объектов из запроса prefetch_related
Я работаю над приложением, похожим на twitter, и у меня есть домашний вид, который отображает твиты и ретвиты текущего пользователя и пользователей, которые следуют за этим пользователем. Я хочу показать информацию о том, кто ретвитнул этот твит для всех ретвитов. В столбце retweeted_by я получаю id пользователя. Набор запросов для этого представления:
def get_queryset(self):
user = self.request.user
tweets = Tweet.objects.filter(Q(user=user) | Q(user__in=user.followees.all())). \
annotate(action_time=F('pub_date'), retweeted_by=Value(0, output_field=BigIntegerField())). \
select_related('user').prefetch_related('likes', 'retweets', 'children', 'mentioned_users')
retweets = Tweet.objects.filter(Q(tweetretweet__user=user) | Q(tweetretweet__user__in=user.followees.all())). \
annotate(action_time=F('tweetretweet__timestamp'), retweeted_by=F('tweetretweet__user')). \
select_related('user').prefetch_related('likes', 'retweets', 'children', 'mentioned_users')
return tweets.union(retweets).order_by('-action_time')
Шаблон для этого представления отображает все твиты в наборе запросов с тегом включения:
@register.inclusion_tag('tweets/short_tweet_snippet.html', takes_context=True)
def render_short_tweet(context, tweet):
var_dict = {
'request': context['view'].request,
'tweet': tweet,
}
# Check if queryset has retweeted_by column
# (i have a lot of views which display tweets, but only some show retweet info)
try:
retweeted_by = tweet.retweeted_by
except AttributeError:
return var_dict
# If retweeted_by value not equal 0
if retweeted_by:
# user = tweet.retweets.filter(pk=retweeted_by).get() (hits the db)
# user = tweet.retweets.get(pk=retweeted_by) (hits the db)
# Doesn't hits the db, but not optimized solution
for user in tweet.retweets.all():
if user.pk == retweeted_by:
retweeted_user = user
var_dict.update(retweeted_user=retweeted_user)
return var_dict
Проблема в том, что когда я хочу получить объект пользователя, который ретвитнул определенный твит, django делает много похожих запросов, но у меня есть все пользователи, которые сделали ретвит для этого твита с помощью prefetch_related('retweets',...). Например, если 'user1', 'user2' и 'user3' ретвитнули 'tweet1', я могу получить всех пользователей с:
users = tweet1.retweets.all()
Но если я хочу получить только 'user1' для этого твита1, он попадает в базу данных с новым запросом.
user1 = tweet1.retweets.get(pk=user1.pk)