Login

Django Generic Paginator

Author:
agusmakmun
Posted:
January 25, 2018
Language:
Python
Version:
Not specified
Tags:
generic pagination paginator listview generic-paginator
Score:
0 (after 0 ratings)

Django Generic Paginator for generic.ListView

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
from django.core.paginator import (Paginator, EmptyPage, PageNotAnInteger)


class GenericPaginator(object):

    """
    class PostList(GenericPaginator, ListView):
        ....

        def get_context_data(self, **kwargs):
            context_data = super(PostList, self).get_context_data(**kwargs)
            context_data['page_range'] = self.get_page_range()
            return context_data
    """

    def get_page_range(self):
        page = self.request.GET.get('page')
        paginate_by = self.paginate_by or 10
        queryset = self.queryset or self.get_queryset()

        # if page is None:
        #    raise Exception('request `?page` is None')

        paginator = Paginator(queryset, paginate_by)

        try:
            objects = paginator.page(page)
        except PageNotAnInteger:
            objects = paginator.page(1)
        except EmptyPage:
            objects = paginator.page(paginator.num_pages)

        index = objects.number - 1
        limit = 3  # limit for show range left and right of number pages
        max_index = len(paginator.page_range)
        start_index = index - limit if index >= limit else 0
        end_index = index + limit if index <= max_index - limit else max_index

        # When you return this, you will getting error
        # `page_range TypeError: sequence index must be integer, not 'slice'`.
        # Because now in django changelog, use `xrange`, and not `range`.
        # See this tickets: https://code.djangoproject.com/ticket/23140
        # >>> page_range  = paginator.page_range[start_index:end_index]
        page_range = list(paginator.page_range)[start_index:end_index]
        return page_range


# USAGE IN THE TEMPLATE
"""
{% if is_paginated %}
  {# `is_paginated` is default bassed in `generic.ListView` #}
  <div class="ui paginations">
    <div class="ui small pagination menu">
      {% if page_obj.has_previous %}
        <a class="item spf-link" href="?page={{ page_obj.previous_page_number }}">&laquo;</a>
      {% endif %}

      <a class="item spf-link" href="?page=1">first</a>

      {% for linkpage in page_range %}
        {% ifequal linkpage page_obj.number %}
          <a class="item active">
            {{ page_obj.number }}
          </a>
        {% else %}
          <a class="item spf-link" href="?page={{ linkpage }}">{{ linkpage }}</a>
        {% endifequal %}
      {% endfor %}

      <a class="item spf-link" href="?page={{ page_obj.paginator.num_pages }}">last</a>

      {% if page_obj.has_next %}
        <a class="item spf-link" href="?page={{ page_obj.next_page_number }}">&raquo;</a>
      {% endif %}
    </div><!-- end /.ui.pagination.menu -->
  </div>
{% endif %}{# endif is_paginated #}
"""

More like this

Comments

Please login first before commenting.