Menu
CoddyTech

تقسيم الصفحات

جزء من قسم واجهات العرض المعتمدة على الأصناف في رحلة Django على Coddy. الدرس 8 من 18.

تعرض صفحة الوظائف كل وظيفة دفعة واحدة، ولن تتسع لألف وظيفة. يقسّم تقسيم الصفحات القائمة إلى صفحات، مع روابط بينها. ينفّذ ListView هذا التقسيم باستخدام سمة واحدة، هي paginate_by، التي تحدد عدد الصفوف في الصفحة.

عند ضبط paginate_by = 20 في قائمة الوصفات، تعرض /recipes/ أول 20 وصفة، بينما تعرض /recipes/?page=2 الوصفات العشرين التالية. أما طلب صفحة تتجاوز النهاية، أو قيمة ليست رقمًا، فيؤدي إلى استجابة 404. لا تحتوي القائمة في القالب إلا على صفوف هذه الصفحة، كما يحصل القالب على is_paginated وpage_obj، أي الصفحة الحالية.

عليك كتابة الروابط باستخدام page_obj: تشير number إلى هذه الصفحة، ويشير paginator.num_pages إلى عدد الصفحات. تكون has_next وhas_previous بقيمة True عندما توجد صفحة بعد هذه الصفحة أو قبلها، وتُعطي next_page_number وprevious_page_number رقمها:

{% if page_obj.has_next %}
  <a href="?page={{ page_obj.next_page_number }}">More recipes</a>
{% endif %}

أبقِ الاختبار حول كل رابط: ففي الصفحة الأخيرة، يؤدي next_page_number إلى خطأ يتسبب في تعطّل الصفحة.

challenge icon

التحدي

سهل

اعرض الوظائف بواقع 5 وظائف في كل صفحة.

  1. في jobs/views.py، اجعل JobListView يعرض 5 وظائف في كل صفحة.
  2. في job_list.html، أضف أسفل القائمة <nav class="pages"> مع رابطين يظهر عليهما النصان Previous وNext كما هما تمامًا، وبينهما Page 1 of 3 من page_obj. اعرض كل رابط فقط عندما تكون صفحته موجودة، وإلا فسيتعطل عرض الصفحة.

افتح /jobs/ واضغط على Next: سترى Page 2 of 3.

جرّب بنفسك

from django.views.generic import DetailView, ListView, TemplateView

from .models import Job


class HomeView(TemplateView):
    template_name = "jobs/home.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["count"] = Job.objects.count()
        context["latest"] = Job.objects.order_by("-posted").first()
        return context


class AboutView(TemplateView):
    template_name = "jobs/about.html"


class JobListView(ListView):
    model = Job
    context_object_name = "jobs"
    ordering = ["-posted"]

    def get_queryset(self):
        jobs = super().get_queryset()
        city = self.request.GET.get("city")
        if city:
            jobs = jobs.filter(city=city)
        return jobs


class JobDetailView(DetailView):
    model = Job

جميع دروس واجهات العرض المعتمدة على الأصناف

تدرّب بنفسك: Playground لـ Django