Проблема оптимизации запросов в Django ORM
Я делаю сайт-блог и столкнулся с некоторыми проблемами с производительностью запросов.
У меня есть 3 модели
- User Model -> Users (To store user email, Password etc)
- Post Model -> Actual Posts
- people Model -> (To store users extra information)
Post Model ->
class Post(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT)
category = models.ForeignKey(Category, on_delete=models.PROTECT)
title = models.CharField(max_length=255,null=True)
description = models.CharField(max_length=1000,null=True)
Likes = models.ManyToManyField(to=User, related_name='Post_likes')
favourites = models.ManyToManyField(to=User,blank=True,related_name="favourite")
Модель человека ->
class People(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
photo = models.ImageField(upload_to='profile_pics', blank=True,null=True)
Phone_number = models.CharField(max_length=255,null=True,blank=True)
Birth_Date = models.DateField(null=True,blank=True)
Created_date = models.DateTimeField(auto_now_add=True)
Updated_date = models.DateTimeField(auto_now=True)
Теперь, поскольку обе эти модели связаны с моделью User. Я хочу запросить модель Post и получить фотографию пользователя в шаблоне. Сейчас, когда я использую post.user.people.photo, для каждого поста генерируется отдельный запрос к БД, что приводит к замедлению работы. Я хотел бы использовать Join здесь, чтобы объединить несколько таблиц и получить все записи сразу.
В настоящее время я использую следующий запрос ->
posts = Post.objects.select_related().prefetch_related('images_set').annotate(comments_Count = Count('comments_post',distinct=True)).annotate(Count('Likes',distinct=True)).all().order_by('-id')
Вы можете выполнить .select_related(…) [Django-doc] на user и people с user__people, так:
posts = Post.objects.select_related(
'user__people', 'category'
).prefetch_related('images_set').annotate(
comments_Count = Count('comments_post',distinct=True),
Count('Likes',distinct=True)
).order_by('-id')
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL[Django-doc] to refer to the user model, than to use theUsermodel [Django-doc] directly. For more information you can see the referencing theUsermodel section of the documentation.