简体   繁体   中英

my django query: how to improve the speed of list view

List page is paginated and displaying only 10 journal posts. Despite this, there are 95 queries being performed. It's affecting the page load speed. Instead of loading <1 second it's taking around 4-5 seconds. Here are my code, please check and let me know how to optimize. views.py

class PostListView(LoginRequiredMixin,ListView):
    model = Post
    paginate_by = 10

    def get_queryset(self):
        qs = super(PostListView, self).get_queryset().filter(Q(
            Q(language_id__in=self.request.user.native_language),
            ~Q(user_id__in=self.request.user.forbidden_user_list))).order_by('-created')
        return qs

    def get_context_data(self, **kwargs):
        context = super(PostListView, self).get_context_data(**kwargs)
        context['list_type'] = 'all'

models.py

class Post(models.Model):
    user = models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    title = models.CharField(max_length=60)
    text = models.TextField()
    native_text = models.TextField(blank=True)
    created = models.DateTimeField(default=timezone.now, db_index=True)
    # updated = models.DateTimeField(auto_now=True)
    # is_corrected = models.BooleanField(default=False)
    users_like = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='posts_liked',
                                        blank=True)
    language = models.ForeignKey('account.Language', on_delete=models.SET_NULL, null=True)

    def __str__(self):
        return self.text

    def get_absolute_url(self):
        return reverse('post-detail', args=[str(self.id)])

    @property
    def get_correctors(self):
        from account.models import Profile as User
        result = list(set(User.objects.all().filter((Q(correctedrows__post_id=self.id) | Q(perfectrows__post_id=self.id) | Q(comment__post_id=self.id)))))
        return result

In your get_queryset method, you should try to use select_related and prefetch_related to get whatever you will use in your template.

For example, if in your template you are doing post.user.name , that is going to cause an additional query. Try something like this:

def get_queryset(self):
        qs = super(PostListView, self).get_queryset().select_related('user', 'language'). prefetch_related('users_like').filter(Q(
            Q(language_id__in=self.request.user.native_language),
            ~Q(user_id__in=self.request.user.forbidden_user_list))).order_by('-created')
        return qs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM