How to cache a paginated Django queryset

前端 未结 3 358
不知归路
不知归路 2021-02-04 21:46

How do you cache a paginated Django queryset, specifically in a ListView?

I noticed one query was taking a long time to run, so I\'m attempting to cache it. The queryset

3条回答
  •  野趣味
    野趣味 (楼主)
    2021-02-04 22:46

    I wanted to paginate my infinite scrolling view on my home page and this is the solution I came up with. It's a mix of Django CCBVs and the author's initial solution.

    The response times, however, didn't improve as much as I would've hoped for but that's probably because I am testing it on my local with just 6 posts and 2 users haha.

        # Import
        from django.core.cache import cache
        from django.core.paginator import InvalidPage
        from django.views.generic.list import ListView
        from django.http Http404
    
        class MyListView(ListView):
        template_name = 'MY TEMPLATE NAME'
        model = MY POST MODEL
        paginate_by = 10
    
    
    
        def paginate_queryset(self, queryset, page_size):
    
            """Paginate the queryset"""
            paginator = self.get_paginator(
                queryset, page_size, orphans=self.get_paginate_orphans(),
                allow_empty_first_page=self.get_allow_empty())
    
            page_kwarg = self.page_kwarg
    
            page = self.kwargs.get(page_kwarg) or self.request.GET.get(page_kwarg) or 1
    
            try:
                page_number = int(page)
    
            except ValueError:
                if page == 'last':
                    page_number = paginator.num_pages
    
                else:
                    raise Http404(_("Page is not 'last', nor can it be converted to an int."))
            try:
                page = paginator.page(page_number)
                cache_key = 'mylistview-%s-%s' % (page_number, page_size)
                retreive_cache = cache.get(cache_key)
    
                if retreive_cache is None:
                    print('re-caching')
                    retreive_cache = super(MyListView, self).paginate_queryset(queryset, page_size)
    
                    # Caching for 1 day
                    cache.set(cache_key, retreive_cache, 86400)
    
                return retreive_cache
            except InvalidPage as e:
                raise Http404(_('Invalid page (%(page_number)s): %(message)s') % {
                    'page_number': page_number,
                    'message': str(e)
                })
    
    

提交回复
热议问题