Opened 2 months ago

Last modified 7 weeks ago

#35452 assigned Cleanup/optimization

Unexpected results when Paginator's orphans is equal or higher than the page size

Reported by: Strapchay Owned by: Ajay Singh
Component: Core (Other) Version: dev
Severity: Normal Keywords: pagination, paginator
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

The documentation https://docs.djangoproject.com/en/4.2/ref/paginator/#django.core.paginator.Paginator.orphans says the orphan would append values which are orphans which don't fit into the context of the per_page of the paginator to the last_page of the paginator if the remaining values is less than or equal to the specified orphan value. However, there seems to be a logical error in how it is implemented. The orphan only applies if the specified orphan value is exactly the value specified and not lesser. And also in situations where the page_size specified is lesser than the orphans, the values of the next page including the orphan are instead added to the intial page which disregards the pagination.

So in a situation where i specify a page_size of 2 and have 7 queryset data and specified the orphans to be 3, it returns only a single page making it returned value 7 and similar if the queryset data is 5 and the orphans is 3, however, if i specify the orphans to be 1 the pagination behaves as expected

Change History (4)

comment:1 by Natalia Bidart, 2 months ago

Triage Stage: UnreviewedAccepted
Type: BugCleanup/optimization
Version: 5.0dev

Hello Strapchay, thank you for your report.

My initial thinking about this report is that having an orphans value bigger than the page size does not make sense. Could you share a valid use case for that?

Having said that, I think this ticket is valid in that the code should either:

  1. enforce that orphans is strictly smaller than the page size (per_page), or
  2. explicitly document that if orphans is equal or higher than per_page, you'll get unexpected results.

Reproducers:

>>> from django.core.paginator import Paginator
>>> p = Paginator([str(i) for i in range(9)], per_page=2, orphans=3)
>>> for i in range(p.num_pages): print(p.page(i+1).object_list)
... 
['0', '1']
['2', '3']
['4', '5', '6', '7', '8']
>>>

>>> p = Paginator([str(i) for i in range(9)], per_page=2, orphans=5)
>>> for i in range(p.num_pages): print(p.page(i+1).object_list)
... 
['0', '1']
['2', '3', '4', '5', '6', '7', '8']

>>> p = Paginator([str(i) for i in range(9)], per_page=3, orphans=3)
>>> for i in range(p.num_pages): print(p.page(i+1).object_list)
... 
['0', '1', '2']
['3', '4', '5', '6', '7', '8']

I'm inclined to do option 1 but we'd need to do it with a deprecation path in case there are code bases out there misusing the orphans value.

comment:2 by Natalia Bidart, 2 months ago

Summary: There seems to an issue with the doc on django's orphans and its implementationUnexpected results when Paginator's orphans is equal or higher than the page size

comment:3 by Strapchay, 2 months ago

I do not have a specific use case for having an orphan greater than the page size. I was only trying to get the results needed from a test case and needed the data gotten back to not break the ui context of amount to fit into the screen and created a base test case which was how I noticed the issue in the first place. I think the first one would be great. Also why not have a warning or an exception raised when the orphan specified is more than the page_size?, or what's your thought on that?

comment:4 by Ajay Singh, 7 weeks ago

Owner: changed from nobody to Ajay Singh
Status: newassigned
Note: See TracTickets for help on using tickets.
Back to Top