Displaying Page Numbers with django-tables2
Asked Answered
E

3

9

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.

Estas answered 7/5, 2013 at 0:12 Comment(0)
B
13

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 :)

Bondstone answered 7/5, 2013 at 22:4 Comment(1)
Thanks! I actually ended up resolving this myself by installing bootstrap-pagination and writing my own pagination function. However, upboated for the response and specificity.Estas
H
5

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 %}
    
Hognut answered 23/5, 2017 at 9:37 Comment(2)
The 'pagina' variable in the line '{% if page == 1 and current_page > 5 or pagina...' should probably be 'page'. I tested with that change and it seems to work as expected but I wasn't able to edit the answer myself since it's less than a 6 character change.Mildred
@Mildred You're right, my mistake... That's what happens when you translate your variable names to English, and don't test the code. Corrected. Thanks!Hognut
A
4

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

Ardy answered 15/5, 2019 at 12:11 Comment(2)
This only changes the style of the table( not the paginator )Slover
FYI as of v2.4.1 if your table's Meta class overrides template_name this will take precedent over whatever is defined in settings.py. See the relevant section in the source codeHeilbronn

© 2022 - 2024 — McMap. All rights reserved.