title: EmptyPage Error in Django pagination
body: <p>I am tring to make digg-style pagination in my django application. I used custom templatetags. First and last pages didnt work and I dont understand how to fix that. However other pages work fine. Where I did mistake?</p>
  
  <p><strong>First page Error:</strong> EmptyPage: That page number is less than 1</p>
  
  <pre><code>Traceback (most recent call last):
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\exception.py", line 39, in inner
      response = get_response(request)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
      response = self.process_exception_by_middleware(e, request)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
      response = wrapped_callback(request, *callback_args, **callback_kwargs)
    File "C:\Users\Nurzhan\PycharmProjects\RMS\project\views.py", line 20, in project_list
      return render(request, 'project/project_list.html', {'projects': projects, 'paginator': paginator})
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\shortcuts.py", line 30, in render
      content = loader.render_to_string(template_name, context, request, using=using)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\loader.py", line 68, in render_to_string
      return template.render(context, request)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\backends\django.py", line 66, in render
      return self.template.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 208, in render
      return self._render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 199, in _render
      return self.nodelist.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 994, in render
      bit = node.render_annotated(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 961, in render_annotated
      return self.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\loader_tags.py", line 174, in render
      return compiled_parent._render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 199, in _render
      return self.nodelist.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 994, in render
      bit = node.render_annotated(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 961, in render_annotated
      return self.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\loader_tags.py", line 70, in render
      result = block.nodelist.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 994, in render
      bit = node.render_annotated(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 961, in render_annotated
      return self.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\library.py", line 225, in render
      _dict = self.func(*resolved_args, **resolved_kwargs)
    File "C:\Users\Nurzhan\PycharmProjects\RMS\project\templatetags\pagination.py", line 48, in custom_paginator
      'previous': page_obj.previous_page_number(),
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\paginator.py", line 136, in previous_page_number
      return self.paginator.validate_number(self.number - 1)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\paginator.py", line 38, in validate_number
      raise EmptyPage('That page number is less than 1')
  django.core.paginator.EmptyPage: That page number is less than 1
  </code></pre>
  
  <p><strong>Last page Error:</strong>  EmptyPage That page contains no results</p>
  
  <pre><code>Traceback (most recent call last):
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\exception.py", line 39, in inner
      response = get_response(request)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
      response = self.process_exception_by_middleware(e, request)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
      response = wrapped_callback(request, *callback_args, **callback_kwargs)
    File "C:\Users\Nurzhan\PycharmProjects\RMS\project\views.py", line 20, in project_list
      return render(request, 'project/project_list.html', {'projects': projects, 'paginator': paginator})
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\shortcuts.py", line 30, in render
      content = loader.render_to_string(template_name, context, request, using=using)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\loader.py", line 68, in render_to_string
      return template.render(context, request)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\backends\django.py", line 66, in render
      return self.template.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 208, in render
      return self._render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 199, in _render
      return self.nodelist.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 994, in render
      bit = node.render_annotated(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 961, in render_annotated
      return self.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\loader_tags.py", line 174, in render
      return compiled_parent._render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 199, in _render
      return self.nodelist.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 994, in render
      bit = node.render_annotated(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 961, in render_annotated
      return self.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\loader_tags.py", line 70, in render
      result = block.nodelist.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 994, in render
      bit = node.render_annotated(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 961, in render_annotated
      return self.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\library.py", line 225, in render
      _dict = self.func(*resolved_args, **resolved_kwargs)
    File "C:\Users\Nurzhan\PycharmProjects\RMS\project\templatetags\pagination.py", line 48, in custom_paginator
      'previous': page_obj.previous_page_number(),
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\paginator.py", line 136, in previous_page_number
      return self.paginator.validate_number(self.number - 1)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\paginator.py", line 38, in validate_number
      raise EmptyPage('That page number is less than 1')
  django.core.paginator.EmptyPage: That page number is less than 1
  [04/Mar/2017 19:13:59] "GET /ru/account/dashboard/project/list/?page=1 HTTP/1.1" 500 152849
  Internal Server Error: /ru/account/dashboard/project/list/
  Traceback (most recent call last):
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\exception.py", line 39, in inner
      response = get_response(request)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
      response = self.process_exception_by_middleware(e, request)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
      response = wrapped_callback(request, *callback_args, **callback_kwargs)
    File "C:\Users\Nurzhan\PycharmProjects\RMS\project\views.py", line 20, in project_list
      return render(request, 'project/project_list.html', {'projects': projects, 'paginator': paginator})
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\shortcuts.py", line 30, in render
      content = loader.render_to_string(template_name, context, request, using=using)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\loader.py", line 68, in render_to_string
      return template.render(context, request)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\backends\django.py", line 66, in render
      return self.template.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 208, in render
      return self._render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 199, in _render
      return self.nodelist.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 994, in render
      bit = node.render_annotated(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 961, in render_annotated
      return self.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\loader_tags.py", line 174, in render
      return compiled_parent._render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 199, in _render
      return self.nodelist.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 994, in render
      bit = node.render_annotated(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 961, in render_annotated
      return self.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\loader_tags.py", line 70, in render
      result = block.nodelist.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 994, in render
      bit = node.render_annotated(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py", line 961, in render_annotated
      return self.render(context)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\library.py", line 225, in render
      _dict = self.func(*resolved_args, **resolved_kwargs)
    File "C:\Users\Nurzhan\PycharmProjects\RMS\project\templatetags\pagination.py", line 49, in custom_paginator
      'next': page_obj.next_page_number(),
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\paginator.py", line 133, in next_page_number
      return self.paginator.validate_number(self.number + 1)
    File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\paginator.py", line 43, in validate_number
      raise EmptyPage('That page contains no results')
  django.core.paginator.EmptyPage: That page contains no results
  [04/Mar/2017 19:16:12] "GET /ru/account/dashboard/project/list/?page=12 HTTP/1.1" 500 152777
  </code></pre>
  
  <p><strong>views.py</strong></p>
  
  <pre><code>def project_list(request):
      objects = Project.objects.filter(status='public', membership__user=request.user)
      paginator = Paginator(objects, 1)
  
      page = request.GET.get('page')
      try:
          projects = paginator.page(page)
      except PageNotAnInteger:
          # If page is not an integer, deliver first page.
          projects = paginator.page(1)
      except EmptyPage:
          # If page is out of range (e.g. 9999), deliver last page of results.
          projects = paginator.page(paginator.num_pages)
  
      return render(request, 'project/project_list.html', {'projects': projects, 'paginator': paginator})
  </code></pre>
  
  <p><strong>pagination.py</strong></p>
  
  <pre><code>from django import template
  
  register = template.Library()
  
  LEADING_PAGE_RANGE_DISPLAYED = TRAILING_PAGE_RANGE_DISPLAYED = 5
  LEADING_PAGE_RANGE = TRAILING_PAGE_RANGE = 4
  NUM_PAGES_OUTSIDE_RANGE = 2
  ADJACENT_PAGES = 2
  
  
  def custom_paginator(context):
      paginator = context['paginator']
      page_obj = context['projects']
      pages = paginator.num_pages
      page = page_obj.number
      in_leading_range = in_trailing_range = False
      pages_outside_leading_range = pages_outside_trailing_range = range(0)
      if pages &lt;= LEADING_PAGE_RANGE_DISPLAYED + NUM_PAGES_OUTSIDE_RANGE + 1:
          in_leading_range = in_trailing_range = True
          page_range = [n for n in range(1, pages + 1)]
      elif page &lt;= LEADING_PAGE_RANGE:
          in_leading_range = True
          page_range = [n for n in range(1, LEADING_PAGE_RANGE_DISPLAYED + 1)]
          pages_outside_leading_range = [n + pages for n in range(0, -NUM_PAGES_OUTSIDE_RANGE, -1)]
      elif page &gt; pages - TRAILING_PAGE_RANGE:
          in_trailing_range = True
          page_range = [n for n in range(pages - TRAILING_PAGE_RANGE_DISPLAYED + 1, pages + 1) if 0 &lt; n &lt;= pages]
          pages_outside_trailing_range = [n + 1 for n in range(0, NUM_PAGES_OUTSIDE_RANGE)]
      else:
          page_range = [n for n in range(page - ADJACENT_PAGES, page + ADJACENT_PAGES + 1) if 0 &lt; n &lt;= pages]
          pages_outside_leading_range = [n + pages for n in range(0, -NUM_PAGES_OUTSIDE_RANGE, -1)]
          pages_outside_trailing_range = [n + 1 for n in range(0, NUM_PAGES_OUTSIDE_RANGE)]
  
      request = context['request']
      params = request.GET.copy()
      if 'page' in params:
          del (params['page'])
      get_params = params.urlencode()
  
      return {
          'pages': pages,
          'page': page,
          'previous': page_obj.previous_page_number(),
          'next': page_obj.next_page_number(),
          'has_previous': page_obj.has_previous(),
          'has_next': page_obj.has_next(),
          'page_range': page_range,
          'in_leading_range': in_leading_range,
          'in_trailing_range': in_trailing_range,
          'pages_outside_leading_range': pages_outside_leading_range,
          'pages_outside_trailing_range': pages_outside_trailing_range,
          'get_params': get_params,
      }
  
  
  register.inclusion_tag("project/pagination.html", takes_context=True)(custom_paginator)
  </code></pre>
  
  <p><strong>project_list.html</strong></p>
  
  <pre><code>{% for project in projects %}
     *** LIST OF PROJECTS HERE ***
  {% endfor %}
  {% custom_paginator %}
  </code></pre>
  
  <p><strong>pagination.html</strong></p>
  
  <pre><code>{% spaceless %}
    {% if has_previous %}
      &lt;li&gt;&lt;a href="{% if get_params %}?{{ get_params }}&amp;{% else %}?{% endif %}page={{ previous }}"&gt;&amp;laquo; Prev&lt;/a&gt;&lt;/li&gt;
    {% endif %}
    {% if not in_leading_range %}
      {% for p in pages_outside_trailing_range %}
        &lt;li&gt;&lt;a href="{% if get_params %}?{{ get_params }}&amp;{% else %}?{% endif %}page={{ p }}"&gt;{{ p }}&lt;/a&gt;&lt;/li&gt;
      {% endfor %}
      &lt;li&gt;&lt;span class="ellipsis"&gt;...&lt;/span&gt;&lt;/li&gt;
    {% endif %}
    {% for p in page_range %}
      {% if p == page %}
        &lt;li&gt;&lt;span class="active"&gt;{{ p }}&lt;/span&gt;&lt;/li&gt;
      {% else %}
        &lt;li&gt;&lt;a href="{% if get_params %}?{{ get_params }}&amp;{% else %}?{% endif %}page={{ p }}"&gt;{{ p }}&lt;/a&gt;&lt;/li&gt;
      {% endif %}
    {% endfor %}
    {% if not in_trailing_range %}
      &lt;li&gt;&lt;span class="ellipsis"&gt;...&lt;/span&gt;&lt;/li&gt;
      {% for p in pages_outside_leading_range reversed %}
        &lt;li&gt;&lt;a href="{% if get_params %}?{{ get_params }}&amp;{% else %}?{% endif %}page={{ p }}"&gt;{{ p }}&lt;/a&gt;&lt;/li&gt;
      {% endfor %}
    {% endif %}
    {% if has_next %}
      &lt;li&gt;&lt;a href="{% if get_params %}?{{ get_params }}&amp;{% else %}?{% endif %}page={{ next }}"&gt;Next &amp;raquo;&lt;/a&gt;&lt;/li&gt;
    {% endif %}
  {% endspaceless %}
  </code></pre>