pagination.txt 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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 parts and handing them over to other
  11. components.
  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
  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 Contacts
  76. class ContactsList(ListView):
  77. paginate_by = 2
  78. model = Contacts
  79. The only thing your users will be missing is a way to navigate to the next or
  80. previous page. To achieve this, add links to the next and previous page, like
  81. shown in the below example ``list.html``.
  82. .. _using-paginator-in-view:
  83. Using ``Paginator`` in a view
  84. =============================
  85. Here's a slightly more complex example using
  86. :class:`~django.core.paginator.Paginator` in a view to paginate a queryset. We
  87. give both the view and the accompanying template to show how you can display
  88. the results. This example assumes you have a ``Contacts`` model that has
  89. already been imported.
  90. The view function looks like this::
  91. from django.core.paginator import Paginator
  92. from django.shortcuts import render
  93. def listing(request):
  94. contact_list = Contacts.objects.all()
  95. paginator = Paginator(contact_list, 25) # Show 25 contacts per page
  96. page = request.GET.get('page')
  97. contacts = paginator.get_page(page)
  98. return render(request, 'list.html', {'contacts': contacts})
  99. In the template :file:`list.html`, you'll want to include navigation between
  100. pages along with any interesting information from the objects themselves:
  101. .. code-block:: html+django
  102. {% for contact in contacts %}
  103. {# Each "contact" is a Contact model object. #}
  104. {{ contact.full_name|upper }}<br>
  105. ...
  106. {% endfor %}
  107. <div class="pagination">
  108. <span class="step-links">
  109. {% if contacts.has_previous %}
  110. <a href="?page=1">&laquo; first</a>
  111. <a href="?page={{ contacts.previous_page_number }}">previous</a>
  112. {% endif %}
  113. <span class="current">
  114. Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
  115. </span>
  116. {% if contacts.has_next %}
  117. <a href="?page={{ contacts.next_page_number }}">next</a>
  118. <a href="?page={{ contacts.paginator.num_pages }}">last &raquo;</a>
  119. {% endif %}
  120. </span>
  121. </div>