صفحه بندی با استفاده از GCBV

سلام

در ادامه پیاده سازی مشابهی را و البته با استفاده از ListView می بینیم.

boards/views.py (مشاهده کد کامل)

class TopicListView(ListView):
    model = Topic
    context_object_name = 'topics'
    template_name = 'topics.html'
    paginate_by = 20

    def get_context_data(self, **kwargs):
        kwargs['board'] = self.board
        return super().get_context_data(**kwargs)

    def get_queryset(self):
        self.board = get_object_or_404(Board, pk=self.kwargs.get('pk'))
        queryset = self.board.topics.order_by('-last_updated').annotate(replies=Count('posts') - 1)
        return queryset

تعامل با paginator در قالب برنامه متفاوت از روش عادی و مبتنی بر توابع است. در قالب، متغیرهای زیر قابل دسترسی اند:

paginator, page_obj, is_paginated, object_list و همچنین متغیری که نام آن را در context_object_name تعریف کرده ایم. در این مورد این متغیرهای اضافه را topics نامگذاری می کنیم که معادل object_list خواهد بود.

و اما get_context_data شیوه ای است که برای اضافه کردن چیزهای مختلف به request در زمان توسعه یک GCBV استفاده می شود.

نکتۀ اساسی در این میان مربوط به ویژگی paginate_by است. در برخی از موارد صرفاً اضافه کردن آن به برنامه کافی است. فراموش نکنید که فایل urls.py نیز نیاز به بروز رسانی دارد.

myproject/urls.py (مشاهده کد کامل)

from django.conf.urls import url
from boards import views

urlpatterns = [
    # ...
    url(r'^boards/(?P<pk>\d+)/$', views.TopicListView.as_view(), name='board_topics'),
]

حالا قالب را درست می کنیم.

templates/topics.html(مشاهده کد کامل)

{% block content %}
  <div class="mb-4">
    <a href="{% url 'new_topic' board.pk %}" class="btn btn-primary">New topic</a>
  </div>

  <table class="table mb-4">
    <!-- table content suppressed -->
  </table>

  {% if is_paginated %}
    <nav aria-label="Topics pagination" class="mb-4">
      <ul class="pagination">
        {% if page_obj.has_previous %}
          <li class="page-item">
            <a class="page-link" href="?page={{ page_obj.previous_page_number }}">Previous</a>
          </li>
        {% else %}
          <li class="page-item disabled">
            <span class="page-link">Previous</span>
          </li>
        {% endif %}

        {% for page_num in paginator.page_range %}
          {% if page_obj.number == page_num %}
            <li class="page-item active">
              <span class="page-link">
                {{ page_num }}
                <span class="sr-only">(current)</span>
              </span>
            </li>
          {% else %}
            <li class="page-item">
              <a class="page-link" href="?page={{ page_num }}">{{ page_num }}</a>
            </li>
          {% endif %}
        {% endfor %}

        {% if page_obj.has_next %}
          <li class="page-item">
            <a class="page-link" href="?page={{ page_obj.next_page_number }}">Next</a>
          </li>
        {% else %}
          <li class="page-item disabled">
            <span class="page-link">Next</span>
          </li>
        {% endif %}
      </ul>
    </nav>
  {% endif %}

{% endblock %}

و حالا هم زمان رسیدگی به فایل تست و ایجاد تغییرات لازم :

boards/tests/test_view_board_topics.py

from django.test import TestCase
from django.urls import resolve
from ..views import TopicListView

class BoardTopicsTests(TestCase):
    # ...
    def test_board_topics_url_resolves_board_topics_view(self):
        view = resolve('/boards/1/')
        self.assertEquals(view.func.view_class, TopicListView)

ترجمۀ اختصاصی توسط تمدن

 

مطلب بعدی:قالب های صفحه بندی با قابلیت استفاده مجدد

مطلب قبلی: صفحه بندی با استفاده از FBV

0 پاسخ

دیدگاه خود را ثبت کنید

تمایل دارید در گفتگو شرکت کنید؟
نظری بدهید!

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *