[Django] #29680: Paginate start with last Page

33 views
Skip to first unread message

Django

unread,
Aug 16, 2018, 11:49:58 AM8/16/18
to django-...@googlegroups.com
#29680: Paginate start with last Page
-------------------------------------+-------------------------------------
Reporter: Dario | Owner: Dario Navin
Navin |
Type: | Status: assigned
Cleanup/optimization |
Component: Generic | Version: 2.1
views |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 1
UI/UX: 0 |
-------------------------------------+-------------------------------------
Hi,

currently you can't set the paginate to start with the last page if no
page is given unless you put in the url.

MultipleObjectMixin:
{{{
page_kwarg = self.page_kwarg
# I suggest removing the static 1 and replace it with a function
called
# get_start_page whose default return value is 1
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."))
}}}

Suggested change:

{{{
page = self.kwargs.get(page_kwarg) or self.request.GET.get(page_kwarg) or
self.get_start_page()
}}}

Default would be 1. Then for starting with the last page someone could set
it to

{{{
def get_start_page(self):
return self.get_paginator().num_pages
}}}


I did search but could not find any report about it.

If someone could approve this, I would submit a fix.

Best regards,

Dario Heinisch

--
Ticket URL: <https://code.djangoproject.com/ticket/29680>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Aug 16, 2018, 3:14:05 PM8/16/18
to django-...@googlegroups.com
#29680: Paginate start with last Page
-------------------------------------+-------------------------------------
Reporter: Dario Navin | Owner: Dario
Type: | Navin
Cleanup/optimization | Status: assigned
Component: Generic views | Version: 2.1
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham):

* easy: 1 => 0


Comment:

What's the use case for starting pagination on the last page? Couldn't you
just reverse the order of whatever you're paginating?

--
Ticket URL: <https://code.djangoproject.com/ticket/29680#comment:1>

Django

unread,
Aug 16, 2018, 4:12:55 PM8/16/18
to django-...@googlegroups.com
#29680: Paginate start with last Page
-------------------------------------+-------------------------------------
Reporter: Dario Navin | Owner: Dario
Type: | Navin
Cleanup/optimization | Status: assigned
Component: Generic views | Version: 2.1
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Dario Navin):

Replying to [comment:1 Tim Graham]:


> What's the use case for starting pagination on the last page? Couldn't
you just reverse the order of whatever you're paginating?

Forums use the same schema as well as displaying messages.

Let's say I have a simple Message model.

I want to display my messages with the latest message being on the bottom:

1. First Message
2. Second Message
3. ....
4. Latest Message

In the current state I would have to order the queryset decending by id in
my view to get the last message on the first page.

{{{
class SingleMessageDetailView(ListView):
model = Message
template_name = 'message.html'
paginate_by = 10
context_object_name = "messages"
ordering = "-id"
}}}

But now I am facing the problem that the last message is the first object
in my queryset.
I could solve it by reversing the queryset in the template but in my
opinion that is not a beautiful code since we have to make two adjustments
at two different ends.


{{{
{% for obj in messages reversed %}
}}}


Having the option to start at the last page would make it easier &
friendlier for development.

The other current option is to use a function based view or to change the
url:


{{{
# Normally I would move the 'page last part' to the absolute url but for
demonstration purpose I have put it in the html code.
<a href="{{ message.get_absolute_url }}?page=last">{{ message.subject
}}</a>
}}}


Also, jumping to the last page is quite common in forums and follows the
"book-style".

--
Ticket URL: <https://code.djangoproject.com/ticket/29680#comment:2>

Django

unread,
Aug 16, 2018, 5:45:29 PM8/16/18
to django-...@googlegroups.com
#29680: Paginate start with last Page
-------------------------------------+-------------------------------------
Reporter: Dario Navin | Owner: Dario
Type: | Navin
Cleanup/optimization | Status: assigned
Component: Generic views | Version: 2.1
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tim Graham):

Maybe I'm missing the point, but I don't recall a forum that used the type
of pagination you describe. It doesn't seem intuitive. Pages are sorted
from newest to oldest but the items within the page are sorted from oldest
to newest?

--
Ticket URL: <https://code.djangoproject.com/ticket/29680#comment:3>

Django

unread,
Aug 16, 2018, 5:53:36 PM8/16/18
to django-...@googlegroups.com
#29680: Paginate start with last Page
-------------------------------------+-------------------------------------
Reporter: Dario Navin | Owner: Dario
Type: | Navin
Cleanup/optimization | Status: assigned
Component: Generic views | Version: 2.1
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Dario Navin):

Here are some examples which use the pagination I described:

1. https://ubuntuforums.org/showthread.php?t=2015424&page=8
2. https://www.wallstreetoasis.com/forums/2019-ft-analyst-recruiting-
timeline?page=1
3. https://python-forum.io/Thread-Enigma-Machine-I-need-help?page=7

--
Ticket URL: <https://code.djangoproject.com/ticket/29680#comment:4>

Django

unread,
Aug 16, 2018, 9:35:57 PM8/16/18
to django-...@googlegroups.com
#29680: Paginate start with last Page
-------------------------------------+-------------------------------------
Reporter: Dario Navin | Owner: Dario
Type: | Navin
Cleanup/optimization | Status: assigned
Component: Generic views | Version: 2.1
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tim Graham):

I'm afraid I'm still not following. All the URLs you gave have `page=X`
and if I remove that, I get the first page. I thought the idea was that
you wanted a URL without `page=X` to show the last page? It looks like
#4919 was implemented to allow `?page=last` to do what you want.

--
Ticket URL: <https://code.djangoproject.com/ticket/29680#comment:5>

Django

unread,
Aug 17, 2018, 5:04:43 AM8/17/18
to django-...@googlegroups.com
#29680: Paginate start with last Page
-------------------------------------+-------------------------------------
Reporter: Dario Navin | Owner: Dario
Type: | Navin
Cleanup/optimization | Status: assigned
Component: Generic views | Version: 2.1
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Dario Navin):

Yes, currently I am using {{{?page=last }}}.

''I thought the idea was that you wanted a URL without page=X to show the
last page?''

That is exactly my idea.

--
Ticket URL: <https://code.djangoproject.com/ticket/29680#comment:6>

Django

unread,
Aug 17, 2018, 12:40:01 PM8/17/18
to django-...@googlegroups.com
#29680: Paginate start with last Page
-------------------------------------+-------------------------------------
Reporter: Dario Navin | Owner: Dario
Type: | Navin
Cleanup/optimization | Status: assigned
Component: Generic views | Version: 2.1
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tim Graham):

I have a doubt that pagination like that is a good practice because a link
to a message on that page would be broken once that message falls off the
first page.

--
Ticket URL: <https://code.djangoproject.com/ticket/29680#comment:7>

Django

unread,
Aug 17, 2018, 5:37:39 PM8/17/18
to django-...@googlegroups.com
#29680: Paginate start with last Page
-------------------------------------+-------------------------------------
Reporter: Dario Navin | Owner: Dario
Type: | Navin
Cleanup/optimization | Status: assigned
Component: Generic views | Version: 2.1
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Dario Navin):

Would you mind explaining what you mean by broken? I do not really get the
downside. I have been using my suggested idea with function based views
for a while and did not run in any problems

--
Ticket URL: <https://code.djangoproject.com/ticket/29680#comment:8>

Django

unread,
Aug 17, 2018, 6:09:56 PM8/17/18
to django-...@googlegroups.com
#29680: Paginate start with last Page
-------------------------------------+-------------------------------------
Reporter: Dario Navin | Owner: Dario
Type: | Navin
Cleanup/optimization | Status: assigned
Component: Generic views | Version: 2.1
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tim Graham):

Say I link to a specific post using a fragment:
https://ubuntuforums.org/showthread.php?t=2015424#post_12095405

If no page number in the query string shows the last page instead of the
first page, then such a link would break once that post drops off the last
page. You'd have the same problem with the `?page=last` approach, I guess.

All in all, `or 1` in the code looks a bit odd to me also, but the
rationale to add a new API to support of style of pagination which I
haven't seen before seems weak. As far as I understand, the links you
provided in comment 4 don't demonstrate the style of pagination you're
requesting (if I remove `?page=` from those links, they all show the first
page).

--
Ticket URL: <https://code.djangoproject.com/ticket/29680#comment:9>

Django

unread,
Aug 21, 2018, 6:51:27 AM8/21/18
to django-...@googlegroups.com
#29680: Paginate start with last Page
-------------------------------------+-------------------------------------
Reporter: Dario Navin | Owner: Dario
Type: | Navin
Cleanup/optimization | Status: closed

Component: Generic views | Version: 2.1
Severity: Normal | Resolution: wontfix
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Carlton Gibson):

* status: assigned => closed
* resolution: => wontfix


Comment:

Given that `?page=last` already exists I'm don't think this merits the
extra method.

If you **really** don't want the query parameter you can always just
override `paginate_queryset()`.

Something like this would do no?:

{{{
page_kwarg = self.page_kwarg
if self.request.GET.get(page_kwarg) is None:
self.kwargs[page_kwarg] = 'last'
return super().paginate_queryset(self, queryset, page_size)
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/29680#comment:10>

Reply all
Reply to author
Forward
0 new messages