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

class PaginatorMixin(object):
    def __init__(self, queryset, numb_pages, request_page):
        self.queryset       = queryset          #egg: models.Post.objects.all()
        self.numb_pages     = numb_pages        #egg: int 10 `is number per page`
        self.request_page   = request_page      #egg: request.GET.get('page')

    def page_numbering(self):
        paginator = Paginator(self.queryset, self.numb_pages)
        try:
            pagination = paginator.page(self.request_page)
        except PageNotAnInteger:
            pagination = paginator.page(1)
        except EmptyPage:
            pagination = paginator.page(paginator.num_pages)

        index       = pagination.number - 1
        limit       = 5 #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

        page_range  = list(paginator.page_range)[start_index:end_index]
        return page_range

    def queryset_paginated(self):
        paginator = Paginator(self.queryset, self.numb_pages)
        try:
            queryset_paginated = paginator.page(self.request_page)
        except PageNotAnInteger:
            queryset_paginated = paginator.page(1)
        except EmptyPage:
            queryset_paginated = paginator.page(paginator.num_pages)

        return queryset_paginated


"""Example:

# 1. your_app/views.py

def homepage(request):
    posts      = Post.objects.published().order_by('-id')
    get_page   = request.GET.get('page')
    NUMB_PAGES = 10

    page_obj   = PaginatorMixin(posts, NUMB_PAGES, get_page).queryset_paginated()
    page_range = PaginatorMixin(posts, NUMB_PAGES, get_page).page_numbering()
    posts = page_obj.object_list
    ctx = {
        'posts': posts,
        'page_obj'    : page_obj,
        'page_range'  : page_range
    }
    return render(request, 'your_app/homepage.html', ctx)



# 2. your_app/templates/your_app/homepage.html

{% if posts %}
  <ul class="pagination">
    <li {% if not page_obj.has_previous %}class="disabled"{% endif %}>
      <a {% if page_obj.has_previous %}href="?page={{ page_obj.previous_page_number }}" aria-label="Previous" {% endif %}><span aria-hidden="true">&laquo;</span></a>
    </li>
    <li><a href="?page=1">First</a></li>
    {% for linkpage in page_range %}
    {% ifequal linkpage page_obj.number %}
    <li class="active">
      <a>{{ page_obj.number }}<span class="sr-only">(current)</span></a>
    </li>
    {% else %}
    <li><a href="?page={{ linkpage }}">{{ linkpage }}</a></li>
    {% endifequal %}
    {% endfor %}
    <li><a href="?page={{ page_obj.paginator.num_pages }}">Last</a></li>
    <li {% if not page_obj.has_next %}class="disabled"{% endif %}>
      <a {% if page_obj.has_next %}href="?page={{ page_obj.next_page_number }}" aria-label="Next" {% endif %}><span aria-hidden="true">&raquo;</span></a>
    </li>
  </ul>
{% endif %}
"""