Hướng dẫn phân trang trong Django
Phân trang cải thiện trải nghiệm người dùng và hiệu suất ứng dụng khi xử lý các tập dữ liệu lớn. Nếu không có hệ thống phân trang, ứng dụng của bạn sẽ luôn bị lag. Với Django, bạn có thể tận dụng hỗ trợ tích hợp cho phân trang để phân trang cho ứng dụng web của mình.
Việc triển khai phân trang trong Django có thể khác nhau tùy thuộc vào việc bạn làm việc với chế độ xem dựa trên lớp hay chức năng. Bất kể phương pháp ưa thích của bạn là gì, các nguyên tắc cơ bản vẫn giống nhau.
Django sử dụng một lớp gọi là người đánh số trang để thực hiện phân trang. Các người đánh số trang lớp cung cấp một số phương pháp mà bạn có thể sử dụng để tùy chỉnh phân trang của mình. Khi khởi tạo các người đánh số trang class, nó nhận hai tham số bắt buộc; dữ liệu để phân trang và số lượng mục sẽ hiển thị trên mỗi trang. Các người đánh số trang nhận tham số tùy chọn thứ ba dành cho trẻ mồ côi để chỉ định số lượng mục tối thiểu sẽ còn lại trên trang cuối cùng. Theo mặc định, giá trị của mồ côi là 0 có nghĩa là tất cả các trang có cùng số mục.
URL cho trang được phân trang Django tương tự như sau: https://example.com/products/?page=3. Các trang tham số trong URL cho Django biết trang mà người dùng muốn xem. Nó cũng giúp Django xác định phần dữ liệu nào sẽ hiển thị cho trang đó.
Mã được sử dụng trong dự án này có sẵn trong kho lưu trữ GitHub và bạn được sử dụng miễn phí theo giấy phép MIT.
Trước khi bạn phân trang trong Django, bạn phải cài đặt Django và thiết lập nó trên máy tính của mình. Sau khi thiết lập Django trên máy tính, bạn nên tạo ứng dụng và mô hình cho dữ liệu của mình. Đây là một mô hình đơn giản mà bạn có thể sao chép:
from django.db import modelsclass 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
Mô hình trên là dành cho một ứng dụng blog. Nó xác định các trường tiêu đề, tác giả và nội dung cho mỗi bài đăng trên blog. Nó cũng có một phương thức trả về tiêu đề bài đăng để có trải nghiệm người dùng tốt hơn trong bảng quản trị.
Di chuyển mô hình của bạn bằng cách chạy lệnh này:
python manage.py makemigrations && python manage.py migrate
Sau khi di chuyển mô hình của bạn, bạn nên điều hướng đến blog>admin.py để đăng ký nó. Đoạn mã sau đăng ký thành công một mô hình có tên Bưu kiện.
from django.contrib import admin
from .models import Post admin.site.register(Post)
Tiếp theo, tạo một siêu người dùng và thêm các bài đăng trong bảng quản trị Django của bạn. Để tạo một siêu người dùng, hãy sử dụng lệnh này:
python manage.py createsuperuser
Lệnh trên sẽ đưa bạn qua quy trình được minh họa trong hình bên dưới:
Sau khi tạo siêu người dùng, hãy chạy máy chủ phát triển của bạn và điều hướng đến bảng quản trị.
python manage.py runserver
Khi máy chủ của bạn khởi động, hãy điều hướng đến http://127.0.0.1:8000/adminđăng nhập và thêm một vài bài đăng.
Tiếp theo, tạo một mẫu HTML để hiển thị bài đăng của bạn trên trình duyệt. Tạo tập tin của bạn trong thư mục sau: your_app/templates/your_app_name/index.html. Nếu bạn không hiểu cách tạo mẫu, hãy đọc hướng dẫn giới thiệu của chúng tôi về kiến trúc MVT của Django.
Django cho phép bạn xây dựng các ứng dụng với chế độ xem dựa trên lớp hoặc chế độ xem dựa trên chức năng. Để phân trang ứng dụng của bạn bằng chế độ xem dựa trên chức năng. Thực hiện theo các bước sau:
- mở của bạn lượt xem.py tập tin và nhập khẩu người đánh số trang lớp học.
from django.core.paginator import Paginator
- Tạo chức năng xem để hiển thị bài đăng trong mẫu HTML của bạn.
from django.shortcuts import render
from .models import Post
from django.core.paginator import Paginatordef list_view(request):
posts = Post.objects.all()
return render(request, 'blog/blog_list_view.html', {'posts':posts})
- Tạo một mẫu URL để hiển thị các bài đăng của bạn trong trình duyệt. Bắt đầu bằng cách định cấu hình mẫu URL trong thư mục dự án của bạn. Mở url.py tệp ở cấp dự án và thêm tệp này vào mô hình url:
from django.urls import includeurlpatterns = [
...,
path('', include('blog.urls')),
]
Trong đoạn mã trên, thay thế Blog với tên ứng dụng của bạn. Nếu bạn không thể phân biệt giữa dự án và ứng dụng, thì bạn nên biết dự án khác với ứng dụng như thế nào trong Django.
Sau khi thực hiện cấu hình trên, hãy tạo một url.py tệp trong thư mục ứng dụng của bạn (trong trường hợp này, đó là tệp Blog thư mục) và thêm đoạn mã này:
from django.urls import path
from .views import list_viewurlpatterns = [
path('', list_view, name='list-view'),
]
Khi bạn chạy máy chủ của mình và điều hướng đến http://127.0.0.1:8000/trình duyệt sẽ hiển thị các bài đăng của bạn theo biểu định kiểu đã chỉ định.
- Sửa đổi chức năng xem của bạn để thêm logic phân trang. Đây là một ví dụ:
def list_view(request):
posts = Post.objects.all()
paginated = Paginator(posts, 3)
page_number = request.GET.get('page')
page = paginated.get_page(page_number)
return render(request, 'blog/blog_list_view.html', {'page':page})
Đoạn mã trên giới thiệu ba biến mới: đánh số trang, số trangVà trang. Mỗi biến làm như sau:
- Các đánh số trang biến đã khởi tạo người đánh số trang lớp học. Trong trường hợp này, dữ liệu được phân trang là bộ truy vấn, bài đăng, và phải mất 3 như số lượng mục để hiển thị trên mỗi trang.
- Các số trang biến lấy số trang từ URL. Ví dụ, trong http://127.0.0.1:8000/?page=2số trang là 2.
- Các trang biến truy xuất trang cụ thể để hiển thị từ đánh số trang Biến đổi.
Đến bây giờ, Django phải phân trang trang của bạn. Bạn có thể điều hướng đến các trang được phân trang cụ thể bằng định dạng URL được hiển thị trong hình ảnh này:
- Sửa đổi mẫu HTML của bạn để hiển thị điều hướng cho các trang được phân trang. Sử dụng các phương pháp có sẵn trong người đánh số trang class cho phép bạn tạo điều hướng đơn giản trên trang của mình. Đây là một ví dụ bạn có thể thêm bên dưới mã HTML ban đầu của mình:
{% 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 %}
Trong đoạn mã trên, các phương pháp sau đây được sử dụng cùng với các câu điều kiện để xác định cách điều hướng phân trang sẽ như thế nào:
- has_previous: Phương thức này trả về ĐÚNG VẬY nếu có một trang trước đó trong dữ liệu được phân trang.
- số_trang_trước: Phương thức này trả về giá trị của trang trước đó.
- trang_range: Phương pháp này cho bạn biết bạn có bao nhiêu trang trong dữ liệu được phân trang của mình.
- con số: Phương thức này trả về giá trị của trang hiện tại.
- num_pages: Phương thức này trả về tổng số trang.
- has_next: Hàm này trả về ĐÚNG VẬY nếu có một trang tiếp theo trong dữ liệu được phân trang.
- next_page_number: Phương thức này trả về giá trị của trang tiếp theo.
Trong dạng xem dựa trên lớp, bạn không phải nhập và khởi tạo người đánh số trang lớp học. Để triển khai phân trang trong chế độ xem dựa trên lớp, bạn nên chỉ định một thuộc tính có tên là phân trang_by. Thực hiện theo các bước sau để phân trang ứng dụng của bạn với chế độ xem dựa trên lớp:
- Viết một khung nhìn dựa trên lớp và chỉ định phân trang_by thuộc tính. Đây là một ví dụ đơn giản:
from .models import Post
from django.views.generic import ListViewclass PostListView(ListView):
model = Post
template_name = 'blog/blog_list_view.html'
context_object_name = 'page'
paginate_by = 2
Chế độ xem trên là phiên bản dựa trên lớp của chế độ xem dựa trên hàm được viết trước đó. Chế độ xem này kế thừa Django’s Chế độ xem danh sách lớp, được sử dụng để liệt kê các mục. Nó định nghĩa logic của nó với các thuộc tính như người mẫu, Tên mẫu, context_object_nameVà phân trang_by. Các phân trang_by thuộc tính xác định số lượng bài đăng sẽ hiển thị trên mỗi trang; trong trường hợp này, 2 bài viết.
- Sau khi bạn tạo chế độ xem của mình, hãy sửa đổi url.py tập tin để sử dụng nó. Đây là một ví dụ đơn giản:
from .views import PostListViewurlpatterns = [
path('', PostListView.as_view(), name='list-view'),
]
- Sửa đổi mẫu HTML của bạn để sử dụng trang_obj cho việc phân trang.
{% 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 %}
Không giống như mẫu HTML cho chế độ xem dựa trên chức năng, mẫu này sử dụng trang_obj thay vì trang để đại diện cho đối tượng trang. Đây là hành vi mặc định cho phân trang dựa trên lớp trong Django.
Phân trang giảm tải trên máy chủ/cơ sở dữ liệu của bạn bằng cách tìm nạp và hiển thị các tập dữ liệu con nhỏ hơn tại một thời điểm. Với phân trang, hiệu suất của các trang web của bạn sẽ tăng lên. Người dùng của bạn cũng sẽ có trải nghiệm tốt khi sử dụng ứng dụng của bạn.
Chế độ xem dựa trên lớp tiết kiệm nhiều thời gian và mã hơn khi so sánh với chế độ xem dựa trên chức năng, nhưng bạn có thể sử dụng một trong hai tùy thuộc vào sở thích và thông số kỹ thuật của dự án.