Django paginator page turns to list

Django paginator page turns to list

I'm trying built a matrimonial site in Django. The following is the code for displaying a single profile at a time.

unfiltered_list = profile_matches
for profile in unfiltered_list:
   print("\n profile:",profile,"\n")
    
profiles_list = profile_matches
paginator = Paginator(profiles_list,1)
page_number = request.GET.get('page', 1)
profiles = paginator.page(page_number)
profile_id = profiles.object_list.values('user_model_for_profile_id')
    

The code works fine if I remove the for loop, but when I try to loop through the unfiltered list, 'profiles' becomes a list even though I haven't touched it, other than creating a variable that references to it. I get an Attribute error saying AttributeError: 'list' object has no attribute 'values'

Is this a problem with Django itself? Or am I missing something?

Answer

This is indeed the case, the reason this happens is because the Paginator in Django slices the queryset [GitHub], indeed:

def page(self, number):
    """Return a Page object for the given 1-based page number."""
    # …
return self._get_page(self.object_list[bottom:top], number, self)

and this will return a QuerySet if the original QuerySet has no result_cache.

But if the QuerySet has results loaded into memory, it returns the sliced result cache [GitHub], indeed:

def __getitem__(self, k):
    """Retrieve an item or slice from the set of results."""
    # …
    if self._result_cache is not None:
        return self._result_cache[k]
    # …

since the ._result_cache is a list of results, the result will indeed be a list.

Pagination is normally the end of the process, so extra ORM calls are quite strange. Moreover, using .values() is a bit of an anti-pattern [django-antipatterns].

If you want to first enumerate over the data, enumerate over a clone of the queryset, so:

for profile in unfiltered_list.all():
    print('\n profile:', profile, '\n')

Enjoyed this article?

Check out more content on our blog or follow us on social media.

Browse more articles