Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.
Sử dụng Limit và Offset trong Django với Python
Trong quá trình phát triển web, việc truy vấn cơ sở dữ liệu để lấy dữ liệu hiển thị trên trang web là điều không thể tránh khỏi. Tuy nhiên, bạn thường chỉ cần một tập hợp con của các hàng dữ liệu thay vì lấy toàn bộ dữ liệu từ cơ sở dữ liệu.
Django cung cấp một cách tiện lợi để giới hạn số lượng đối tượng được trả về từ một QuerySet bằng cách sử dụng cú pháp cắt (slicing), tương đương với các mệnh đề LIMIT và OFFSET trong SQL. Trong bài viết này, bạn sẽ học cách sử dụng cú pháp này để tối ưu hóa các truy vấn dữ liệu trong Django, giúp cải thiện hiệu suất ứng dụng của bạn.
Giới thiệu về Limit và Offset trong Django
Trong thực tế, bạn hiếm khi lấy tất cả các hàng từ một hoặc nhiều bảng trong cơ sở dữ liệu. Thay vào đó, bạn chỉ lấy một tập hợp con các hàng để hiển thị trên một trang web.
Django sử dụng cú pháp cắt (slicing) để giới hạn một QuerySet đến một số lượng đối tượng cụ thể. Phía sau, Django thực thi một câu lệnh SELECT của SQL với các mệnh đề LIMIT và OFFSET.
Bài viết này được đăng tại [free tuts .net]
Giả sử bạn muốn truy cập 10 hàng đầu tiên trong một bảng, bạn có thể sử dụng cú pháp cắt sau:
Entity.objects.all()[:10]
Do bảng lưu trữ các hàng theo một thứ tự không xác định, "10 đối tượng đầu tiên" trở nên không thể đoán trước.
Vì vậy, bạn nên luôn sắp xếp kết quả trước khi cắt truy vấn. Ví dụ, đoạn mã sau đây lấy 10 hàng đầu tiên được sắp xếp theo field_name
:
Entity.objects.all().order_by(field_name)[:10]
Để lấy các hàng từ 10 đến 20, bạn có thể sử dụng cú pháp cắt sau:
Entity.objects.all().order_by(field_name)[10:20]
Nhìn chung, cú pháp để giới hạn kết quả như sau:
Entity.objects.all()[Offset:Offset+Limit]
Trong cú pháp này, Offset
là số hàng bạn muốn bỏ qua và Limit
là số hàng bạn muốn lấy.
Lưu ý rằng Django không hỗ trợ indexing âm như:
Entity.objects.all().order_by(field_name)[-10]
Ngoài ra, khi bạn cắt một QuerySet, Django sẽ trả về một QuerySet mới.
Để lấy hàng đầu tiên hoặc hàng cuối cùng, bạn nên sử dụng phương thức first()
hoặc last()
vì nếu QuerySet trống và bạn sử dụng cú pháp cắt:
Entity.objects.all().order_by(field_name)[0]
bạn sẽ gặp phải ngoại lệ IndexError
.
Ví dụ về Limit và Offset trong Django
Mình sẽ sử dụng mô hình Employee
từ ứng dụng HR cho ví dụ. Mô hình Employee
ánh xạ đến bảng hr_employee
:
Ví dụ sau lấy 10 nhân viên đầu tiên được sắp xếp theo tên đầu tiên:
>>> Employee.objects.all().order_by('first_name')[:10] SELECT "hr_employee"."id", "hr_employee"."first_name", "hr_employee"."last_name", "hr_employee"."contact_id", "hr_employee"."department_id" FROM "hr_employee" ORDER BY "hr_employee"."first_name" ASC LIMIT 10 Execution time: 0.000000s [Database: default] <QuerySet [<Employee: Aaron Pearson>, <Employee: Adam Crane>, <Employee: Adam Stewart>, <Employee: Adrienne Green>, <Employee: Alan Johnson>, <Employee: Alexa West>, <Employee: Alicia Wyatt>, <Employee: Amanda Benson>, <Employee: Amber Brown>, <Employee: Amy Lopez>]>
Ví dụ sau bỏ qua 10 hàng đầu tiên và lấy 10 hàng tiếp theo từ bảng hr_employee
:
>>> Employee.objects.order_by('first_name')[10:20] SELECT "hr_employee"."id", "hr_employee"."first_name", "hr_employee"."last_name", "hr_employee"."contact_id", "hr_employee"."department_id" FROM "hr_employee" ORDER BY "hr_employee"."first_name" ASC LIMIT 10 OFFSET 10 Execution time: 0.001001s [Database: default] <QuerySet [<Employee: Amy Lee>, <Employee: Andre Perez>, <Employee: Andrea Mcintosh>, <Employee: Andrew Dixon>, <Employee: Andrew Guerra>, <Employee: Ann Chang>, <Employee: Anne Odom>, <Employee: Anthony Fuentes>, <Employee: Anthony Welch>, <Employee: Ashley Brown>]>
Kết bài
Việc sử dụng cú pháp cắt mảng trong Django để giới hạn số lượng đối tượng trả về bởi một QuerySet không chỉ giúp bạn dễ dàng truy xuất các tập hợp con của dữ liệu mà còn tối ưu hóa hiệu suất ứng dụng và quản lý dữ liệu hiệu quả hơn. Bằng cách áp dụng các mệnh đề tương đương LIMIT và OFFSET trong SQL, bạn có thể kiểm soát lượng dữ liệu được xử lý và hiển thị, từ đó giảm tải cho cơ sở dữ liệu và cải thiện trải nghiệm người dùng. Hiểu và sử dụng thành thạo cú pháp này là một kỹ năng quan trọng cho bất kỳ nhà phát triển Django nào nhằm đảm bảo ứng dụng hoạt động mượt mà và hiệu quả.