Skip to content

Instantly share code, notes, and snippets.

@rg3915
Last active September 22, 2023 16:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rg3915/01ca76f099f431c24bc0536bef83076b to your computer and use it in GitHub Desktop.
Save rg3915/01ca76f099f431c24bc0536bef83076b to your computer and use it in GitHub Desktop.
Pagination similar at Django Admin - view pagination - method pagination and mantain pagination e mantem paginacao
<div class="row text-center">
<div class="col-lg-12">
<ul class="pagination">
{% if page_obj.has_previous %}
<li><a href="?page={{ page_obj.previous_page_number }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">&laquo;</a></li>
{% endif %}
{% for pg in page_obj.paginator.page_range %}
<!-- Sempre mostra as 3 primeiras e 3 últimas páginas -->
{% if pg == 1 or pg == 2 or pg == 3 or pg == page_obj.paginator.num_pages or pg == page_obj.paginator.num_pages|add:'-1' or pg == page_obj.paginator.num_pages|add:'-2' %}
{% if page_obj.number == pg %}
<li class="active"><a href="?page={{ pg }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">{{ pg }}</a></li>
{% else %}
<li><a href="?page={{ pg }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">{{ pg }}</a></li>
{% endif %}
{% else %}
{% if page_obj.number == pg %}
<li class="active"><a href="?page={{ pg }}">{{ pg }}</a></li>
{% elif pg > page_obj.number|add:'-4' and pg < page_obj.number|add:'4' %}
<!-- Mostra 3 páginas antes e 3 páginas depois da atual -->
<li><a href="?page={{ pg }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">{{ pg }}</a></li>
{% elif pg == page_obj.number|add:'-4' or pg == page_obj.number|add:'4' %}
<li><a href="">...</a></li>
{% endif %}
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li><a href="?page={{ page_obj.next_page_number }}&q={{ request.GET.q }}">&raquo;</a></li>
{% endif %}
</ul>
</div>
</div>
{% load url_replace %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?{% url_replace page=page_obj.previous_page_number %}">&laquo;</a>
</li>
{% endif %}
{% for pg in page_obj.paginator.page_range %}
<!-- Sempre mostra as 2 primeiras e as 2 últimas páginas -->
{% if pg == 1 or pg == 2 or pg == page_obj.paginator.num_pages or pg == page_obj.paginator.num_pages|add:'-1' %}
{% if page_obj.number == pg %}
<li class="page-item active">
<a class="page-link" href="?{% url_replace page=pg %}">{{ pg }}</a>
</li>
{% else %}
<li class="page-item">
<a class="page-link" href="?{% url_replace page=pg %}">{{ pg }}</a>
</li>
{% endif %}
{% else %}
{% if page_obj.number == pg %}
<li class="page-item active">
<a class="page-link" href="?{% url_replace page=pg %}">{{ pg }}</a>
</li>
{% elif pg > page_obj.number|add:'-3' and pg < page_obj.number|add:'3' %}
<!-- Mostra 2 páginas antes e 2 páginas depois da atual -->
<li class="page-item">
<a class="page-link" href="?{% url_replace page=pg %}">{{ pg }}</a>
</li>
{% elif pg == page_obj.number|add:'-3' or pg == page_obj.number|add:'3' %}
<li class="page-item">
<a class="page-link" href=".">...</a>
</li>
{% endif %}
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?{% url_replace page=page_obj.next_page_number %}">&raquo;</a>
</li>
{% endif %}
</ul>
<!-- pagination.html -->
<div class="intro-y flex flex-wrap sm:flex-row sm:flex-nowrap items-center mt-3">
<nav class="w-full sm:w-auto sm:mr-auto">
<ul class="pagination">
<!-- Início da paginação -->
<!-- Primeira página -->
{% if page_obj.number != 1 %}
<li class="page-item">
<a class="page-link" href="?page=1&search={{ request.GET.search }}"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" icon-name="chevrons-left" class="lucide lucide-chevrons-left w-4 h-4" data-lucide="chevrons-left"><polyline points="11 17 6 12 11 7"></polyline><polyline points="18 17 13 12 18 7"></polyline></svg> </a>
</li>
{% endif %}
<!-- Página anterior -->
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}&search={{ request.GET.search }}"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" icon-name="chevron-left" class="lucide lucide-chevron-left w-4 h-4" data-lucide="chevron-left"><polyline points="15 18 9 12 15 6"></polyline></svg> </a>
</li>
{% endif %}
<!-- ... -->
<!-- {% if page_obj.number != 1 %}
<li class="page-item"> <a class="page-link" href="#">...</a> </li>
{% endif %} -->
<!-- Páginas do meio -->
{% for pg in page_obj.paginator.page_range %}
<!-- Sempre mostra as 2 primeiras e 2 últimas páginas -->
{% if pg == 1 or pg == 2 or pg == page_obj.paginator.num_pages or pg == page_obj.paginator.num_pages|add:'-1' %}
<li class="page-item {% if page_obj.number == pg %}active{% endif %}"> <a class="page-link" href="?page={{ pg }}&search={{ request.GET.search }}">{{ pg }}</a> </li>
{% else %}
{% if page_obj.number == pg %}
<li class="page-item active"><a class="page-link" href="?page={{ pg }}">{{ pg }}</a></li>
{% elif pg > page_obj.number|add:'-3' and pg < page_obj.number|add:'3' %}
<!-- Mostra 2 páginas antes e 2 páginas depois da atual -->
<li class="page-item"><a class="page-link" href="?page={{ pg }}&search={{ request.GET.search }}">{{ pg }}</a></li>
{% elif pg == page_obj.number|add:'-4' or pg == page_obj.number|add:'4' %}
<li class="page-item"> <a class="page-link" href="#">...</a> </li>
{% endif %}
{% endif %}
{% endfor %}
<!-- ... -->
<!-- {% if page_obj.number != page_obj.paginator.num_pages %}
<li class="page-item"> <a class="page-link" href="#">...</a> </li>
{% endif %} -->
<!-- Próxima página -->
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}&search={{ request.GET.search }}"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" icon-name="chevron-right" class="lucide lucide-chevron-right w-4 h-4" data-lucide="chevron-right"><polyline points="9 18 15 12 9 6"></polyline></svg> </a>
</li>
{% endif %}
<!-- Última página -->
{% if page_obj.number != page_obj.paginator.num_pages %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}&search={{ request.GET.search }}"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" icon-name="chevrons-right" class="lucide lucide-chevrons-right w-4 h-4" data-lucide="chevrons-right"><polyline points="13 17 18 12 13 7"></polyline><polyline points="6 17 11 12 6 7"></polyline></svg> </a>
</li>
{% endif %}
<!-- Fim da paginação -->
</ul>
</nav>
<select class="w-20 form-select box mt-3 sm:mt-0">
<option>10</option>
<option>25</option>
<option>35</option>
<option>50</option>
</select>
</div>
{% load pagination_tags %}
<a href="{% paginated_link page_obj 1 request.GET %}">First</a>
{% if page_obj.has_previous %}
<a href="{% paginated_link page_obj page_obj.previous_page_number request.GET %}">Previous</a>
{% endif %}
{% for pg in page_obj.paginator.page_range %}
<a href="{% paginated_link page_obj pg request.GET %}">{{ pg }}</a>
{% endfor %}
{% if page_obj.has_next %}
<a href="{% paginated_link page_obj page_obj.next_page_number request.GET %}">Next</a>
{% endif %}
<a href="{% paginated_link page_obj paginator.num_pages request.GET %}">Last</a>
from django import template
from urllib.parse import urlencode
register = template.Library()
@register.simple_tag
def paginated_link(page_obj, page_number, request_get):
params = request_get.copy()
params["page"] = page_number
if page_number == 1:
del params["page"]
query_string = urlencode(params)
return f"?{query_string}"
# https://stackoverflow.com/a/62587351/802542
from django import template
register = template.Library()
@register.simple_tag(takes_context=True)
def url_replace(context, **kwargs):
query = context['request'].GET.copy()
query.pop('page', None)
query.update(kwargs)
return query.urlencode()
def pagination(request, items_per_page, object_list):
# Paginação
# https://docs.djangoproject.com/en/4.1/topics/pagination/#using-paginator-in-a-view-function
paginator = Paginator(object_list, items_per_page)
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
return page_obj
def my_list(request):
page_obj = pagination(request=request, items_per_page=20, object_list=object_list)
context = {'page_obj': page_obj}
return render(request, template_name, context)
@rg3915
Copy link
Author

rg3915 commented Sep 3, 2019

Aqui tem algumas diferenças nas classes de li e a :
<li class="page-item"><a class="page-link"
https://gist.github.com/luxu/a3a6a6f764b32f5cb7a1e41517a99ff9

@bahiamartins
Copy link

Seu script nao considera o numero max de paginas, assim o melhor que já consegui foi:

             {% if pages.has_other_pages %}
                <ul class="pagination">
                  {% if pages.has_previous %}
                  <li>
                    <a href="?page=1{% querystring request %}">&laquo;&laquo;</a>
                  </li>
                  <li>
                    <a href="?page={{ pages.previous_page_number }}{% querystring request %}">&laquo;</a>
                  </li>
                  {% else %}
                  <li class="disabled">
                    <span>&laquo;&laquo;</span>
                  </li>
                  <li class="disabled">
                    <span>&laquo;</span>
                  </li>
                  {% endif %}
                  
                  {% for pg in pages.paginator.page_range %}
                
                  {% if pg > pages.number|add:"-4" and pg < pages.number|add:"4" %}
                  <li class="{% if pages.number == pg %}active{% endif %}">
                    <a href="?page={{ pg }}{% querystring request %}">
                      {{ pg }}
                    </a>
                  </li>
                  {% endif %}
                  
                  
                  {% endfor %}
                  {% if pages.has_next %}
                  <li>
                    <a href="?page={{ pages.next_page_number }}{% querystring request %}">&raquo;</a>
                  </li>
                  <li>
                    <a href="?page={{ pages.paginator.num_pages }}{% querystring request %}">&raquo;&raquo;</a>
                  </li>
                  {% else %}
                  <li class="disabled">
                    <span>&raquo;</span>
                  </li>
                  <li class="disabled">
                    <span>&raquo;&raquo;</span>
                  </li>
                  {% endif %}
                </ul>
                {% endif %}
            </div>

@rg3915
Copy link
Author

rg3915 commented Jul 18, 2020

Para manter o filtro aplicado na paginação você pode usar o comando request.GET.urlencode

{% if request.GET.urlencode %}
  &{{ request.GET.urlencode }}
{% endif %}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment