Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Pagination from ?page= to /page/

Tags:

django

I have this view:

class PageView(ListView):
    # ... code ...
    paginate_by = 4

In template I have something like:

<div class="pagination">
          <span class="page-links">
              {% if page_obj.has_previous %}
                  <a href="{{ request.path }}?page={{ page_obj.previous_page_number }}">previous</a>
              {% endif %}
              <span class="page-current">
                  Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
              </span>
              {% if page_obj.has_next %}
                  <a href="{{ request.path }}?page={{ page_obj.next_page_number }}">next</a>
              {% endif %}
          </span>
        </div>

How can I transform GET variable ?page=number to look like /page/number/ in django?

like image 965
yierstem Avatar asked Oct 17 '22 13:10

yierstem


1 Answers

I cannot test it now but you should be able to re-use all of ListView.

Have a look at django.views.generic.list.MultipleObjectMixin#paginate_queryset:

def paginate_queryset(self, queryset, page_size):
    """
    Paginate the queryset, if needed.
    """
    paginator = self.get_paginator(
        queryset, page_size, orphans=self.get_paginate_orphans(),
        allow_empty_first_page=self.get_allow_empty())
    page_kwarg = self.page_kwarg

    # HERE
    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."))
    try:
        page = paginator.page(page_number)
        return (paginator, page, page.object_list, page.has_other_pages())
    except InvalidPage as e:
        raise Http404(_('Invalid page (%(page_number)s): %(message)s') % {
            'page_number': page_number,
            'message': str(e)
        })

This means that Django looks for the page number first in the view's kwargs, and then in the get parameters.

The values in self.kwargs come from the view's own **kwargs - see django.views.generic.base.View#as_view. This means you should be able to just define a URL like url(r'^event/(?P<page>'d+)/$' and use it with your existing CBV - it should pick up the page number on its own.

like image 168
Kos Avatar answered Oct 21 '22 05:10

Kos