Django paginator page turns to list

Django paginator page turns to list
django
Ethan Jackson

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

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

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

Related Articles