pagination.txt 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. ==========
  2. Pagination
  3. ==========
  4. Django provides high-level and low-level ways to help you manage paginated data
  5. -- that is, data that's split across several pages, with "Previous/Next" links.
  6. The ``Paginator`` class
  7. =======================
  8. Under the hood, all methods of pagination use the
  9. :class:`~django.core.paginator.Paginator` class. It does all the heavy lifting
  10. of actually splitting a ``QuerySet`` into :class:`~django.core.paginator.Page`
  11. objects.
  12. Example
  13. =======
  14. Give :class:`~django.core.paginator.Paginator` a list of objects, plus the
  15. number of items you'd like to have on each page, and it gives you methods for
  16. accessing the items for each page::
  17. >>> from django.core.paginator import Paginator
  18. >>> objects = ['john', 'paul', 'george', 'ringo']
  19. >>> p = Paginator(objects, 2)
  20. >>> p.count
  21. 4
  22. >>> p.num_pages
  23. 2
  24. >>> type(p.page_range)
  25. <class 'range_iterator'>
  26. >>> p.page_range
  27. range(1, 3)
  28. >>> page1 = p.page(1)
  29. >>> page1
  30. <Page 1 of 2>
  31. >>> page1.object_list
  32. ['john', 'paul']
  33. >>> page2 = p.page(2)
  34. >>> page2.object_list
  35. ['george', 'ringo']
  36. >>> page2.has_next()
  37. False
  38. >>> page2.has_previous()
  39. True
  40. >>> page2.has_other_pages()
  41. True
  42. >>> page2.next_page_number()
  43. Traceback (most recent call last):
  44. ...
  45. EmptyPage: That page contains no results
  46. >>> page2.previous_page_number()
  47. 1
  48. >>> page2.start_index() # The 1-based index of the first item on this page
  49. 3
  50. >>> page2.end_index() # The 1-based index of the last item on this page
  51. 4
  52. >>> p.page(0)
  53. Traceback (most recent call last):
  54. ...
  55. EmptyPage: That page number is less than 1
  56. >>> p.page(3)
  57. Traceback (most recent call last):
  58. ...
  59. EmptyPage: That page contains no results
  60. .. note::
  61. Note that you can give ``Paginator`` a list/tuple, a Django ``QuerySet``,
  62. or any other object with a ``count()`` or ``__len__()`` method. When
  63. determining the number of objects contained in the passed object,
  64. ``Paginator`` will first try calling ``count()``, then fallback to using
  65. ``len()`` if the passed object has no ``count()`` method. This allows
  66. objects such as Django's ``QuerySet`` to use a more efficient ``count()``
  67. method when available.
  68. Paginating a ``ListView``
  69. =========================
  70. :class:`django.views.generic.list.ListView` provides a builtin way to paginate
  71. the displayed list. You can do this by adding a
  72. :attr:`~django.views.generic.list.MultipleObjectMixin.paginate_by` attribute to
  73. your view class, for example::
  74. from django.views.generic import ListView
  75. from myapp.models import Contact
  76. class ContactList(ListView):
  77. paginate_by = 2
  78. model = Contact
  79. This limits the number of objects per page and adds a ``paginator`` and
  80. ``page_obj`` to the ``context``. To allow your users to navigate between pages,
  81. add links to the next and previous page, in your template like this:
  82. .. code-block:: html+django
  83. {% for contact in page_obj %}
  84. {# Each "contact" is a Contact model object. #}
  85. {{ contact.full_name|upper }}<br>
  86. ...
  87. {% endfor %}
  88. <div class="pagination">
  89. <span class="step-links">
  90. {% if page_obj.has_previous %}
  91. <a href="?page=1">&laquo; first</a>
  92. <a href="?page={{ page_obj.previous_page_number }}">previous</a>
  93. {% endif %}
  94. <span class="current">
  95. Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
  96. </span>
  97. {% if page_obj.has_next %}
  98. <a href="?page={{ page_obj.next_page_number }}">next</a>
  99. <a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
  100. {% endif %}
  101. </span>
  102. </div>
  103. .. _using-paginator-in-view:
  104. Using ``Paginator`` in a view function
  105. ======================================
  106. Here's an example using :class:`~django.core.paginator.Paginator` in a view
  107. function to paginate a queryset::
  108. from django.core.paginator import Paginator
  109. from django.shortcuts import render
  110. from myapp.models import Contact
  111. def listing(request):
  112. contact_list = Contact.objects.all()
  113. paginator = Paginator(contact_list, 25) # Show 25 contacts per page.
  114. page_number = request.GET.get('page')
  115. page_obj = paginator.get_page(page_number)
  116. return render(request, 'list.html', {'page_obj': page_obj})
  117. In the template :file:`list.html`, you can include navigation between pages in
  118. the same way as in the template for the ``ListView`` above.