Finalmente saí do zero com a tal paginação de resultados no projeto final da pós. Apesar de ter tentado o digg_pagination, endless_pagination e mais algumas soluções prontas, devido à dificuldade de integrar (será que é tão difícil escrever uma boa documentação das coisas que fazemos? Até mesmo o JQuery UI e o YUI pecam nisso nas páginas oficiais.) resolvi criar minha própria função para paginar a queryset.
Muito provável que tenha bugs, porque não foi testada exaustivamente, mas por enquanto está servindo.
utils.py
#--------------------------------------------------
# Constantes da paginação.
#--------------------------------------------------
PER_PAGE = 5
PAGE_RANGE = 10
NUM_PAGES_OUTSIDE_RANGE = 2
LEADING_PAGE_RANGE = 5
views.py
#coding:utf-8
from django.template.loader import render_to_string
from django.core.paginator import QuerySetPaginator
from models import *
from utils import *
def monta_paginacao(pagina, paginado):
'''
Monta a navegação entre a páginas como no site Digg.com
'''
# Se a página especificada ultrapassar o limite, redefine para a última
if pagina >= paginado.paginator.num_pages:
pagina = paginado.paginator.num_pages
if paginado.paginator.num_pages > PAGE_RANGE :
paginas_finais = range(paginado.paginator.num_pages - NUM_PAGES_OUTSIDE_RANGE + 1, paginado.paginator.num_pages + 1)
if pagina <= PAGE_RANGE - NUM_PAGES_OUTSIDE_RANGE:
paginas_visiveis = range(1, PAGE_RANGE + 1)
paginas_iniciais = ''
else:
paginas_visiveis = range(pagina - LEADING_PAGE_RANGE, (pagina + LEADING_PAGE_RANGE) % paginado.paginator.num_pages)
paginas_iniciais = range(1, NUM_PAGES_OUTSIDE_RANGE + 1)
mod_inicial = (1 + LEADING_PAGE_RANGE) % paginado.paginator.num_pages
mod_atual = (pagina + LEADING_PAGE_RANGE) % paginado.paginator.num_pages
if( mod_atual < mod_inicial or mod_atual == paginado.paginator.num_pages - 1):
paginas_finais = ''
paginas_visiveis = range(paginado.paginator.num_pages - mod_inicial, paginado.paginator.num_pages + 1)
else:
if (paginado.paginator.num_pages > 1):
paginas_visiveis = range(1, paginado.paginator.num_pages + 1)
else:
paginas_visiveis = ''
paginas_iniciais = paginas_finais = ''
return pagina, paginas_visiveis, paginas_iniciais, paginas_finais
def listagem_principal(request, ordenacao = 'envio', pagina = 1):
resultado = Arquivo.objects.order_by(ordenacao)
if ordenacao == 'envio' or ordenacao == 'downloads':
resultado = resultado.reverse()
try:
pagina = int(pagina)
except:
pagina = 1
paginado = QuerySetPaginator(resultado, PER_PAGE).page(pagina)
atual, paginas_visiveis, paginas_iniciais, paginas_finais = monta_paginacao(pagina, paginado)
contexto = {
'resultados': paginado,
'ordenacao': ordenacao,
'sequencia_visiveis': paginas_visiveis,
'paginas_iniciais': paginas_iniciais,
'paginas_finais': paginas_finais,
'atual': atual
}
template = render_to_string('listagem.html', contexto)
return HttpResponse(template)
O template da paginação foi criado em um arquivo separado para ser incluido no template da listagem, que utiliza JQuery para remover os estilos de acordo com certas condições.
paginacao.html
<div class="paginacao">
<ul id="pagination-flickr">
<li id="1st"><a href="javascript:listagem('{{ ordenacao }}', 1);">Primeira</a></li>
<li id="pxpag"><a href="javascript:listagem('{{ ordenacao }}', {{ atual|add:1 }});">Próxima > ></a></li>
{% for pagina in paginas_iniciais %}
<li><a href="javascript:listagem('{{ ordenacao }}', {{ pagina }});" >{{ pagina }}</a></li>
{% endfor %}
{% if paginas_iniciais %}
<li>...</li>
{% endif %}
{% for pagina in sequencia_visiveis %}
{% ifnotequal pagina atual %}
<li><a href="javascript:listagem('{{ ordenacao }}', {{ pagina }});" >{{ pagina }}</a></li>
{% else %}
<li class="active">{{ pagina }}</li>
{% endifnotequal %}
{% endfor %}
{% if paginas_finais %}
<li>...</li>
{% endif %}
{% for pagina in paginas_finais %}
<li><a href="javascript:listagem('{{ ordenacao }}', {{ pagina }});">{{ pagina }}</a></li>
{% endfor %}
<li id="antpag"><a href="javascript:listagem('{{ ordenacao }}', {{ atual|add:-1 }});">< < Anterior</a></li>
<li id="nth"><a href="javascript:listagem('{{ ordenacao }}', {{ resultados.paginator.num_pages }});">Última</a></li>
</ul>
</div>
listagem.html
<script type="text/javascript">
function listagem(chave, pagina) {
$.post('/principal/listagem/' + chave + '/' + pagina + '/', {}, function(resposta) {
if(chave == 'envio')
$("#ui-tabs-8").html(resposta);
else if (chave == 'nome')
$("#ui-tabs-13").html(resposta);
else if (chave == 'downloads')
$("#ui-tabs-15").html(resposta);
});
}
function aplicarEstilos() {
var elemento = '';
var link = '';
var texto = '';
if ( {{ atual }} == '1' ) {
elemento = $("#1st");
link = elemento.find('a');
texto = elemento.text();
link.remove();
elemento.text(texto);
elemento.addClass('previous-off');
elemento = $("#antpag");
link = elemento.find('a');
texto = elemento.text();
link.remove();
elemento.text(texto);
elemento.addClass('previous-off');
} else if ( {{ atual }} == {{ resultados.paginator.num_pages }} ) {
elemento = $("#pxpag");
link = elemento.find('a');
texto = elemento.text();
link.remove();
elemento.text(texto);
elemento.addClass('next-off');
elemento = $("#nth");
link = elemento.find('a');
texto = elemento.text();
link.remove();
elemento.text(texto);
elemento.addClass('next-off');
}
}
$(document).ready(function() {
$('.link_pagina').click(function () {
var pagina_destino = $(this).attr('pag');
var chave = $(this).attr('chave');
listagem(chave, pagina_destino);
});
aplicarEstilos();
});
</script>
<!-- PAGINAÇÂO DOS RESULTADOS -->
{% include "paginacao.html" %}
<table border="0" cellspacing="30" id="listagem_principal">
{% for arquivo in resultados.object_list %}
<tr>
<td class="celula_listagem">
<table width="100%">
<tr>
<td valign="top" width="50%">
<p><strong>Nome:</strong> {{ arquivo.nome }}</p>
<p><strong>Tipo:</strong> {{ arquivo.tipo.tipo }}</p>
<p><strong>Autor:</strong> {{ arquivo.usuario.username }}</p>
<p><strong>Data:</strong> {{ arquivo.envio }}</p>
</td>
<td valign="top" width="50%">
<p><strong>Descrição:</strong> {{ arquivo.descricao }}</p>
</td>
</tr>
</table>
</td>
</tr>
{% endfor %}
</table>
<!-- PAGINAÇÂO DOS RESULTADOS -->
{% include "paginacao.html" %}
O css utilizado foi o do Flickr, encontrado nesse site: http://woork.blogspot.com/2008/03/perfect-pagination-style-using-css.html
0 Reply to "Paginação"
Leave a Comment
Postar um comentário