با پیاده سازی صفحه بندی، کارایی و مقیاس پذیری برنامه جنگو خود را افزایش دهید. در اینجا همه چیزهایی است که برای شروع باید بدانید.
صفحه بندی تجربه کاربر و عملکرد برنامه را در هنگام برخورد با مجموعه داده های بزرگ بهبود می بخشد. بدون وجود سیستم صفحه بندی، برنامه شما در بیشتر مواقع با تاخیر مواجه می شود. با جنگو، می توانید از پشتیبانی داخلی صفحه بندی برای صفحه بندی برنامه وب خود استفاده کنید.
نحوه کار صفحه بندی در جنگو
پیادهسازی صفحهبندی در جنگو بسته به اینکه با نماهای کلاس محور یا مبتنی بر عملکرد کار میکنید، میتواند متفاوت باشد. صرف نظر از روش ترجیحی شما، اصول اساسی یکسان باقی می مانند.
جنگو از کلاسی به نام Paginator برای پیاده سازی صفحه بندی استفاده می کند. کلاس Paginator چندین روش ارائه می دهد که می توانید از آنها برای سفارشی کردن صفحه بندی خود استفاده کنید. هنگام مقداردهی اولیه کلاس Paginator، دو پارامتر اجباری می گیرد. داده هایی که باید صفحه بندی شوند و تعداد مواردی که در هر صفحه نمایش داده می شود. صفحهساز سومین پارامتر اختیاری را برای یتیمان دریافت میکند تا حداقل تعداد آیتمهایی را که باید در صفحه آخر باقی بمانند را مشخص کند. به طور پیش فرض، مقدار orphans 0 است به این معنی که همه صفحات دارای تعداد یکسانی هستند.
URL برای صفحه صفحه بندی شده جنگو مشابه این است: https://example.com/products/?page=3. پارامتر صفحه در URL به جنگو می گوید که کاربر می خواهد کدام صفحه را ببیند. همچنین به جنگو کمک می کند تا مشخص کند کدام بخش از داده ها را برای آن صفحه نمایش دهد.
کد مورد استفاده در این پروژه در a موجود است
مخزن GitHub
و استفاده از آن تحت مجوز MIT برای شما رایگان است.
پروژه جنگو خود را برای صفحه بندی تنظیم کنید
قبل از صفحه بندی در جنگو، باید جنگو را نصب کرده باشید و آن را بر روی رایانه خود تنظیم کرده باشید. پس از راه اندازی جنگو بر روی رایانه خود، باید یک برنامه و یک مدل برای داده های خود ایجاد کنید. در اینجا یک مدل ساده است که می توانید کپی کنید:
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=255)
author = models.CharField(max_length=50)
content = models.TextField('Post content')
def __str__(self):
return self.title
مدل بالا برای یک برنامه وبلاگ است. فیلدهای عنوان، نویسنده و محتوا را برای هر پست وبلاگ تعریف می کند. همچنین روشی دارد که عنوان پست را برای تجربه کاربری بهتر در پنل مدیریت برمی گرداند.
با اجرای این دستور مدل خود را مهاجرت کنید:
python manage.py makemigrations && python manage.py migrate
پس از انتقال مدل خود، باید به blog>admin.py بروید تا آن را ثبت کنید. کد زیر مدلی به نام Post را با موفقیت ثبت می کند.
from django.contrib import admin
from .models import Post # replace 'Post' with your model name
admin.site.register(Post)
در مرحله بعد، یک ابر کاربر ایجاد کنید و پست ها را در پنل مدیریت جنگو خود اضافه کنید. برای ایجاد superuser از این دستور استفاده کنید:
python manage.py createsuperuser
دستور بالا شما را از طریق فرآیند نشان داده شده در تصویر زیر راهنمایی می کند:
پس از ایجاد یک ابر کاربر، سرور توسعه خود را اجرا کرده و به پنل مدیریت بروید.
python manage.py runserver
هنگامی که سرور شما شروع به کار کرد، به http://127.0.0.1:8000/admin بروید، وارد شوید و چند پست اضافه کنید.
در مرحله بعد، یک قالب HTML ایجاد کنید تا پستهای خود را در مرورگر رندر کنید. فایل خود را در دایرکتوری زیر ایجاد کنید: your_app/templates/your_app_name/index.html. اگر نحوه ایجاد الگوها را نمی دانید، راهنمای مقدماتی معماری MVT جنگو را بخوانید.
صفحه بندی جنگو در یک نمای مبتنی بر عملکرد
جنگو به شما امکان می دهد برنامه هایی را با نماهای کلاس محور یا نماهای مبتنی بر عملکرد بسازید. برای صفحه بندی برنامه خود با استفاده از نمای مبتنی بر تابع. این مراحل را دنبال کنید:
- فایل views.py خود را باز کنید و کلاس Paginator را وارد کنید.
from django.core.paginator import Paginator
- یک تابع view برای ارائه پست ها در قالب HTML خود ایجاد کنید.
from django.shortcuts import render
from .models import Post
from django.core.paginator import Paginator
def list_view(request):
posts = Post.objects.all()
return render(request, 'blog/blog_list_view.html', {'posts':posts})
- یک الگوی URL برای نمایش پست های خود در مرورگر ایجاد کنید. با پیکربندی الگوی URL در فهرست پروژه خود شروع کنید. فایل urls.py را در سطح پروژه باز کنید و این را به الگوهای url اضافه کنید:
from django.urls import include
urlpatterns = [
...,
path('', include('blog.urls')),
]
در قطعه کد بالا، وبلاگ را با نام برنامه خود جایگزین کنید. اگر نمی توانید بین یک پروژه و یک برنامه تمایز قائل شوید، باید بدانید که یک پروژه چه تفاوتی با یک برنامه در جنگو دارد.
پس از انجام تنظیمات بالا، یک فایل urls.py در فهرست برنامه خود ایجاد کنید (در این مورد، پوشه وبلاگ است) و این قطعه کد را اضافه کنید:
from django.urls import path
from .views import list_view
urlpatterns = [
path('', list_view, name='list-view'),
]
هنگامی که سرور خود را اجرا می کنید و به http://127.0.0.1:8000/ می روید، مرورگر پست های شما را مطابق با شیوه نامه مشخص شده شما نمایش می دهد.
- تابع view خود را برای اضافه کردن منطق صفحه بندی تغییر دهید. در اینجا یک مثال است:
def list_view(request):
posts = Post.objects.all()
paginated = Paginator(posts, 3)
page_number = request.GET.get('page') #Get the requested page number from the URL
page = paginated.get_page(page_number)
return render(request, 'blog/blog_list_view.html', {'page':page})
قطعه کد بالا سه متغیر جدید را معرفی می کند: paginated، page_number و page. هر متغیر کارهای زیر را انجام می دهد:
- متغیر صفحه بندی شده کلاس Paginator را مقداردهی اولیه کرد. در این سناریو، داده هایی که باید صفحه بندی شوند مجموعه پرس و جو، پست ها هستند و تعداد آیتم هایی که در هر صفحه نمایش داده می شود 3 مورد است.
- متغیر page_number شماره صفحه را از URL دریافت می کند. به عنوان مثال، در http://127.0.0.1:8000/?page=2، شماره صفحه 2 است.
- متغیر page صفحه خاصی را برای ارائه از متغیر صفحهبندی شده بازیابی میکند.
جنگو باید تا الان صفحه شما را صفحه بندی کرده باشد. می توانید با استفاده از فرمت URL نشان داده شده در این تصویر به صفحات صفحه بندی شده خاصی پیمایش کنید:
- الگوی HTML خود را برای نمایش پیمایش برای صفحات صفحه بندی شده تغییر دهید. استفاده از متدهای موجود در کلاس Paginator شما را قادر می سازد تا پیمایش ساده ای را در صفحه خود ایجاد کنید. در اینجا یک مثال وجود دارد که می توانید در زیر کد HTML اولیه خود اضافه کنید:
{% if page.has_previous %}
<a href="?page={{page.previous_page_number}}"
class="btn btn-secondary mx-2">Previous</a>
{% endif %}
<a href="?page=1" class="btn btn-secondary">First</a>
{% for num in page.paginator.page_range %}
{% if num == page.number %}
<span>{{ num }}</span>
{% else %}
<a href="?page={{num}}" class="btn btn-secondary mx-2">
{{ num }}
</a>
{% endif %}
{% endfor %}
<a href="?page={{page.paginator.num_pages}}" class="btn btn-secondary mx-2">
Last
</a>
{% if page.has_next %}
<a href="?page={{page.next_page_number}}" class="btn btn-secondary mx-2">
Next
</a>
{% endif %}
در قطعه کد بالا، از روشهای زیر همراه با عبارات شرطی استفاده میشود تا مشخص شود که پیمایش صفحهبندی چگونه خواهد بود:
- has_previous: اگر صفحه قبلی در داده های صفحه بندی شده وجود داشته باشد، این روش True را برمی گرداند.
- previous_page_number: این روش مقدار صفحه قبلی را برمی گرداند.
- page_range: این روش به شما این امکان را می دهد که بدانید چند صفحه در داده های صفحه بندی شده خود دارید.
- number: این روش مقدار صفحه فعلی را برمی گرداند.
- num_pages: این روش تعداد کل صفحات را برمی گرداند.
- has_next: اگر صفحه بعدی در داده های صفحه بندی شده باشد، این تابع True را برمی گرداند.
- next_page_number: این روش مقدار صفحه بعد را برمی گرداند.
صفحه بندی جنگو در یک نمای کلاس محور
در نمای مبتنی بر کلاس، لازم نیست کلاس Paginator را وارد و مقداردهی اولیه کنید. برای پیاده سازی صفحه بندی در نمای کلاس محور، باید یک ویژگی به نام paginate_by را مشخص کنید. این مراحل را دنبال کنید تا برنامه خود را با نمای کلاسی صفحه بندی کنید:
- یک نمای مبتنی بر کلاس بنویسید و صفت paginate_by را مشخص کنید. در اینجا یک مثال ساده است:
from .models import Post
from django.views.generic import ListView
class PostListView(ListView):
model = Post
template_name = 'blog/blog_list_view.html'
context_object_name = 'page'
paginate_by = 2
نمای بالا نسخه کلاس محور نمای تابعی است که قبلا نوشته شده بود. این نمای کلاس ListView جنگو را به ارث می برد که برای فهرست کردن آیتم ها استفاده می شود. منطق خود را با ویژگی هایی مانند model، template_name، context_object_name و paginate_by تعریف می کند. صفت paginate_by تعیین می کند که چه تعداد پست در هر صفحه نمایش داده شود. در این مورد 2 پست
- پس از ایجاد نمای خود، فایل urls.py خود را برای استفاده از آن تغییر دهید. در اینجا یک مثال ساده است:
from .views import PostListView
urlpatterns = [
path('', PostListView.as_view(), name='list-view'),
]
- الگوی HTML خود را برای استفاده از page_obj برای صفحه بندی تغییر دهید.
{% if page_obj.has_previous %}
<a href="?page={{page_obj.previous_page_number}}"
class="btn btn-secondary mx-2">Previous</a>
{% endif %}
<a href="?page=1" class="btn btn-secondary">First</a>
{% for num in page_obj.paginator.page_range %}
{% if num == page_obj.number %}
<span class="current-page">{{ num }}</span>
{% else %}
<a href="?page={{num}}" class="btn btn-secondary mx-2">
{{ num }}
</a>
{% endif %}
{% endfor %}
<a href="?page={{page_obj.paginator.num_pages}}"
class="btn btn-secondary mx-2">
Last
</a>
{% if page.has_next %}
<a href="?page={{page_obj.next_page_number}}"
class="btn btn-secondary mx-2">
Next
</a>
{% endif %}
بر خلاف قالب HTML برای نمای مبتنی بر تابع، این الگو به جای page از page_obj برای نمایش شی صفحه استفاده می کند. این رفتار پیشفرض برای صفحهبندی مبتنی بر کلاس در جنگو است.
از صفحه بندی برای مقیاس پذیر کردن برنامه خود استفاده کنید
صفحهبندی با واکشی و نمایش زیرمجموعههای کوچکتر دادهها در یک زمان، بار روی سرور/پایگاه داده را کاهش میدهد. با صفحه بندی، عملکرد وب سایت های شما افزایش می یابد. کاربران شما نیز در هنگام استفاده از اپلیکیشن شما تجربه خوبی خواهند داشت.
نماهای مبتنی بر کلاس در مقایسه با نماهای مبتنی بر عملکرد، زمان و کد بیشتری را صرفه جویی می کنند، اما بسته به اولویت و مشخصات پروژه می توانید از یکی از آنها استفاده کنید.