Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Displaying Page Numbers with django-tables2

I'm currently displaying a dataset using django-tables2.

The docs make no mention of this in particular, so I'm guessing this'll take probably some table overriding - but, I'm hopeful someone out there has already accomplished this.

How can I render page numbers using django-tables2 below my table? What I'd like to be able to display is a horizontal list of page numbers that the user can click.

Thanks in advance.

like image 485
geogaddi Avatar asked May 07 '13 00:05

geogaddi


3 Answers

Pagination is introduced in version# >= 2.0.0 https://django-tables2.readthedocs.io/en/latest/pages/CHANGELOG.html

Simply add following code in settings.py. Pagination with number will be rendered with bootstap 4 style. Make sure you have bootstrap 4 reference in html template.

DJANGO_TABLES2_TEMPLATE = 'django_tables2/bootstrap4.html'

And check out more styles in documentation. https://django-tables2.readthedocs.io/en/latest/pages/custom-rendering.html#available-templates

like image 138
Yiqing Lan Avatar answered Nov 14 '22 05:11

Yiqing Lan


you need to create a custom page rendering template - you don't need to override any classses.

To do that, start by copying the file

PYTHON\Lib\site-packages\django_tables2\templates\django_tables2\table.html

to the templates directory inside your django application and rename it to mytable.html or whatever else you like.

Now, you need to change the pagination block of that file. There are many ways to do what you like, but a simple way is to add the following lines inside the pagination block (you may remove or keep the other things that are there depending on your specific needs):

{% block pagination.allpages %}
  {% for p in table.paginator.page_range %}
    <a href="{% querystring table.prefixed_page_field=p %}">{{ p }}</a>
  {% endfor %}
{% endblock pagination.allpages %}

Finally, to use your template, just pass your custom template name to the render_table command:

{% load render_table from django_tables2 %}
...
{% render_table table "mytable.html" %}

This is very simple and will give you trouble if you have many pages (so you have to use some ifs to check the number of pages through the table.paginator.num_pages variable). Also, you may highlight the current page and disable the link by using the table.page.number variable.

The above are left as an excersise to the reader :)

like image 20
Serafeim Avatar answered Nov 14 '22 03:11

Serafeim


Improving on @Serafeim answer (or solving the exercise he left): Here is a pagination block which, using only Django template syntax, renders page numbers that:

  • are enclosed in a <ul> HTML block, whith CSS classes that "play well" with Bootstrap;

  • if there are more than 8 pages, at most 3 pages below and above current page are shown;

  • first and last pages are always shown, with ellipsis between them and the start or end of the range (if needed).

     {% with current_page=table.page.number page_count=table.paginator.num_pages rows_per_page=table.page.object_list|length total_rows=table.page.paginator.count %}
     {% block pagination %}
     <ul class="pagination">
         {% block pagination.allpages %}
             <li class="current">
                 {% blocktrans %}Page {% endblocktrans %}
             </li>
             {% for page in table.paginator.page_range %}
                 {% with range_start=current_page|add:"-3" range_end=current_page|add:"3" page_count_minus_5=page_count|add:"-5" page_count_minus_1=page_count|add:"-1" %}
                     {% if page == current_page %}
                         <li class="active">
                             <span>{{ page }}</span>
                         </li>
                     {% elif page == 1 or page >= range_start and page <= range_end or page == page_count %}
                         <li class="next">
                             <a href="{% querystring table.prefixed_page_field=page %}">{{ page }}</a>
                         </li>
                     {% endif %}
                     {% if page == 1 and current_page > 5 or page == page_count_minus_1 and current_page <= page_count_minus_5 %}
                         <li class="current">...</li>
                     {% endif %}
                 {% endwith %}
             {% endfor %}
         {% endblock pagination.allpages %}
    
         {% block pagination.cardinality %}
             <li class="cardinality">
                 {% if total_rows != rows_per_page %}{% blocktrans %}
                     {{ rows_per_page }} of {{ total_rows }}{% endblocktrans %}
                 {% else %}
                     {{ total_rows }}
                 {% endif %} 
                 {% if total_rows == 1 %}
                     {{ table.data.verbose_name }}
                 {% else %}
                     {{ table.data.verbose_name_plural }}
                 {% endif %}
             </li>
         {% endblock pagination.cardinality %}
     </ul>
     {% endblock pagination %}
     {% endwith %}
    
like image 5
Jose Francisco Lopez Pimentel Avatar answered Nov 14 '22 05:11

Jose Francisco Lopez Pimentel