pagination.txt 4.6 KB

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