Pagination in Wagtail

django pagination
django custom pagination
django pagination limit page range
wagtail custom serializer
wagtail github
wagtail api

I'm fairly new to Wagtail, and I am in the process of creating a site that will have a Resources (blog) section and I'm not sure how to implement pagination so that there are only 5 posts on each page and the user has to click a number (1, 2, 3, etc.) to go to the next page to see the next 5 posts.

I have this in my template for the pagination section of the resource/blog index page:

<ul class="pagination">
  <li><a href="#"><i class="fa fa-angle-left"></i></a></li>
  <li class="active"><a href="#">1</a></li>
  <li><a href="#">2</a></li>
  <li><a href="#">3</a></li>
  <li><a href="#"><i class="fa fa-angle-right"></i></a></li>
</ul>

What code do I need to incorporate to make this functional? Thanks in advance.

Django provides the module django.core.paginator for this purpose: https://docs.djangoproject.com/en/1.10/topics/pagination/ . Using this within Wagtail is very similar to the examples in the Django documentation - the only real difference is that when you're setting up the Paginator object to be passed to the template, you do that with a get_context method on the page model, instead of a view function. Your model definition will look something like this:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

class ResourceIndexPage(Page):
    # ...
    def get_context(self, request):
        context = super(ResourceIndexPage, self).get_context(request)

        # Get the full unpaginated listing of resource pages as a queryset -
        # replace this with your own query as appropriate
        all_resources = ResourcePage.objects.live()

        paginator = Paginator(all_resources, 5) # Show 5 resources per page

        page = request.GET.get('page')
        try:
            resources = paginator.page(page)
        except PageNotAnInteger:
            # If page is not an integer, deliver first page.
            resources = paginator.page(1)
        except EmptyPage:
            # If page is out of range (e.g. 9999), deliver last page of results.
            resources = paginator.page(paginator.num_pages)

        # make the variable 'resources' available on the template
        context['resources'] = resources

        return context

Within your template, you can now loop over the items using {% for resource in resources %}, and display the pagination links as follows:

<ul class="pagination">
  {% if resources.has_previous %}
    <li><a href="?page={{ resources.previous_page_number }}"><i class="fa fa-angle-left"></i></a></li>
  {% endif %}
  {% for page_num in resources.paginator.page_range %}
    <li {% if page_num == resources.number %}class="active"{% endif %}><a href="?page={{ page_num }}">{{ page_num }}</a></li>
  {% endfor %}
  {% if resources.has_next %}
    <li><a href="?page={{ resources.next_page_number }}"><i class="fa fa-angle-right"></i></a></li>
  {% endif %}
</ul>

How to Paginate Your Wagtail Pages, The paginate function in wagtail.utils.pagination has been deprecated in favour of the django.core.paginator.Paginator.get_page method introduced in Django  In case it's useful to anyone, I wanted this to work as closely as possible to the class-based view ListView, and so I ended up with this:. from django.core.paginator import Paginator, InvalidPage from django.http import Http404 from django.utils.translation import gettext as _ from wagtail.core.models import Page class ArticleListPage(Page): # Some Page variables set here.

I very much appreciate that you got me here - thanks so much for the assist. I had to make some adjustments to make it work. Here's the model if anyone comes across the same issue:

class NewsIndexPage(Page):
intro = RichTextField(blank=True)

def get_context(self, request):
    context = super(NewsIndexPage, self).get_context(request)

    # Get the full unpaginated listing of resource pages as a queryset -
    # replace this with your own query as appropriate
    blogpages = self.get_children().live().order_by('-first_published_at')

    paginator = Paginator(blogpages, 3) # Show 3 resources per page

    page = request.GET.get('page')
    try:
        blogpages = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        blogpages = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        blogpages = paginator.page(paginator.num_pages)

    # make the variable 'resources' available on the template
    context['blogpages'] = blogpages

    return context

...and here's the HTML:

<ul class="pagination">
    {% if blogpages.has_previous %}
      <li>
        <a href="?page={{ blogpages.previous_page_number }}"><i class="fa fa-angle-left"></i></a>
      </li>
    {% endif %}
    {% for page_num in blogpages.paginator.page_range %}
      <li {% if page_num == blogpages.number %} class="active"{% endif %}>
        <a href="?page={{ page_num }}">{{ page_num }}</a>
      </li>
    {% endfor %}
    {% if resources.has_next %}
      <li>
        <a href="?page={{ blogpages.next_page_number }}"><i class="fa fa-angle-right"></i></a>
      </li>
      {% endif %}
  </ul>

It works like a charm - and adds to the learning curve!

Pagination in Wagtail, Wagtail API v2 Usage Guide. Fetching content. Example response; Custom page fields in the API; Pagination; Ordering. Random ordering. Filtering; Filtering by  A pagination plugin app for django wagtail CMS. A simple Django Wagtail app to add paginated pages under a root page using a mixin /template tag approach.

In case it's useful to anyone, I wanted this to work as closely as possible to the class-based view ListView, and so I ended up with this:

from django.core.paginator import Paginator, InvalidPage
from django.http import Http404
from django.utils.translation import gettext as _

from wagtail.core.models import Page

class ArticleListPage(Page):

    # Some Page variables set here. #

    # Pagination variables:
    paginator_class = Paginator
    paginate_by = 10
    page_kwarg = 'page'
    paginate_orphans = 0
    allow_empty = False

    def get_context(self, request):
        context = super().get_context(request)

        queryset = Page.objects.live()

        paginator, page, queryset, is_paginated = self.paginate_queryset(
                                        queryset, self.paginate_by, request)
        context.update({
            'paginator': paginator,
            'page_obj': page,
            'is_paginated': is_paginated,
            'object_list': queryset,
        })

        return context

    def paginate_queryset(self, queryset, page_size, request):
        """
        Adapted from the ListView class-based view.
        Added the request argument.
        """
        paginator = self.paginator_class(
                                    queryset,
                                    self.paginate_by,
                                    orphans=self.paginate_orphans,
                                    allow_empty_first_page=self.allow_empty)
        page_kwarg = self.page_kwarg
        page = 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 will give you the same paginator, page_obj, is_paginated and object_list variables in your template that you would get with a normal Django ListView.

(Using python 3, Django 2.1 and Wagtail 2.3.)

Wagtail 2.5 release notes, from collections import OrderedDict. from django.conf import settings. from rest_framework.pagination import BasePagination. from rest_framework.​response  Wagtail Paginated Subpages. A simple Django Wagtail app to add paginated pages under a root page using a mixin /template tag approach. Adds paginated urls under and page where the mixin is used:

Wagtail API v2 Usage Guide, Paginator and search pagination expect different parameters for page # kaedroho added a commit to kaedroho/wagtail that referenced this  A ParentalKey works similarly to a ForeignKey, but also defines BlogPageGalleryImage as a “child” of the BlogPage model, so that it’s treated as a fundamental part of the page in operations like submitting for moderation, and tracking revision history. image is a ForeignKey to Wagtail’s built-in Image model, where the images themselves are stored.

wagtail/pagination.py at master · wagtail/wagtail · GitHub, Use Django-el-pagination to provide pagination in wagtail. To make our blog support  The genus Motacilla was introduced by the Swedish naturalist Carl Linnaeus in 1758 in the tenth edition of his Systema Naturae. The type species is the white wagtail. Motacilla is the Latin name for the pied wagtail; although actually a diminutive of motare, "to move about", from medieval times it led to the misunderstanding of cilla as "tail".

Paginator and search pagination expect different parameters for , A simple Django Wagtail app to add paginated pages under a root page using a mixin /template tag approach. Adds paginated urls under and  In this lesson we are going to learn how to add a basic StreamField to a a generic Wagtail CMS Page. We'll create a new app from scratch, and this StreamField will have a title and text (using

Comments
  • Just wanted to add that I have used the following around the last <li></li> to only show the next arrow if there is a next page - {% if resources.has_next %} {% endif %}
  • Nice. This works really well. Is there any way to update this so I can use nice urls that have /page/1/ in? Currently I am hacking around but it's pretty messy!
  • @Designer023 Check out RoutablePageMixin: docs.wagtail.io/en/v1.13.1/reference/contrib/routablepage.html