Opened 6 years ago

Closed 6 years ago

#29680 closed Cleanup/optimization (wontfix)

Paginate start with last Page

Reported by: Dario Navin Owned by: Dario Navin
Component: Generic views Version: 2.1
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

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

Change History (10)

comment:1 by Tim Graham, 6 years ago

Easy pickings: unset

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

in reply to:  1 comment:2 by Dario Navin, 6 years ago

Replying to 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".

comment:3 by Tim Graham, 6 years ago

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?

comment:5 by Tim Graham, 6 years ago

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.

comment:6 by Dario Navin, 6 years ago

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.

comment:7 by Tim Graham, 6 years ago

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.

comment:8 by Dario Navin, 6 years ago

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

comment:9 by Tim Graham, 6 years ago

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).

comment:10 by Carlton Gibson, 6 years ago

Resolution: wontfix
Status: assignedclosed

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)
Note: See TracTickets for help on using tickets.
Back to Top