I’m trying to get rid of unnecessary SQL queries using select_related and prefetch_related, but for some reason they only helped me get rid of two unnecessary queries. I thought maybe I could change the SQL query, but that didn’t help either.
My class
class GameDetail(LoginRequiredMixin, DetailView):
model = Game
context_object_name = 'game'
template_name = 'main/game_detail.html'
def get_queryset(self):
return Game.objects.prefetch_related(
Prefetch('comments', queryset=Comment.objects.select_related('author'))
)
def post(self, request, **kwargs):
comment_form = CommentForm(request.POST)
if comment_form.is_valid():
user_comment = comment_form.save(commit=False)
slug = self.kwargs['slug']
game = self.get_object()
user_comment.game = game
user_comment.author = request.user
user_comment.save()
return redirect('game_detail', slug=slug)
if 'delete_comment' in request.POST:
if request.user.is_authenticated:
slug = self.kwargs['slug']
comment_id = request.POST.get('comment_id')
comment = get_object_or_404(Comment, pk=comment_id)
if comment.author == request.user:
comment.delete()
return redirect('game_detail', slug=slug)
return self.render_to_response(
self.get_context_data(form=comment_form))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
comments = Comment.objects.filter(game=self.object).select_related('author')
for comment in comments:
comment.str_value = comment.text
context['comments'] = comments
context['game'] = self.object
context['form'] = CommentForm
return context
My model
class Comment(MPTTModel):
game = models.ForeignKey(
Game, on_delete=models.CASCADE,
related_name='comments',
)
parent = TreeForeignKey(
'self',
on_delete=models.CASCADE,
null=True,
blank=True,
related_name='children',
db_index=True,
)
author = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='comments_author',
db_index=True
)
text = models.TextField()
time_add = models.DateTimeField(auto_now_add=True)
status = models.BooleanField(default=True)
class MPTTMeta:
ordering_insertion_by = ['status']
def __str__(self):
return f'{self.author}:{self.text}'