DJANGO
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

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.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

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:

django orm employee table png

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ả.

Cùng chuyên mục:

Hướng dẫn xây dựng Command-Line Interface (CLI) bằng Quo trong Python

Hướng dẫn xây dựng Command-Line Interface (CLI) bằng Quo trong Python

Hướng dẫn toàn diện về module datetime trong Python

Hướng dẫn toàn diện về module datetime trong Python

Cách truy cập và thiết lập biến môi trường trong Python

Cách truy cập và thiết lập biến môi trường trong Python

Lớp dữ liệu (Data Classes) trong Python với decorator @dataclass

Lớp dữ liệu (Data Classes) trong Python với decorator @dataclass

Từ khóa yield trong Python

Từ khóa yield trong Python

Sự khác biệt giữa sort() và sorted() trong Python

Sự khác biệt giữa sort() và sorted() trong Python

Sử dụng Poetry để quản lý dependencies trong Python

Sử dụng Poetry để quản lý dependencies trong Python

Định dạng chuỗi Strings trong Python

Định dạng chuỗi Strings trong Python

Một tác vụ phổ biến khi làm việc với danh sách trong Python

Một tác vụ phổ biến khi làm việc với danh sách trong Python

Làm việc với các biến môi trường trong Python

Làm việc với các biến môi trường trong Python

Sự khác biệt giữa set() và frozenset() trong Python

Sự khác biệt giữa set() và frozenset() trong Python

Sự khác biệt giữa iterator và iterable trong Python

Sự khác biệt giữa iterator và iterable trong Python

Cách làm việc với file tarball/tar trong Python

Cách làm việc với file tarball/tar trong Python

Chuyển đổi kiểu dữ liệu trong Python

Chuyển đổi kiểu dữ liệu trong Python

Sự khác biệt giữa toán tử == và is trong Python

Sự khác biệt giữa toán tử == và is trong Python

Làm việc với file ZIP trong Python

Làm việc với file ZIP trong Python

Cách sử dụng ThreadPoolExecutor trong Python

Cách sử dụng ThreadPoolExecutor trong Python

Sự khác biệt giữa byte objects và string trong Python

Sự khác biệt giữa byte objects và string trong Python

Xử lý độ chính xác các hàm floor, ceil, round, trunc, format  trong Python

Xử lý độ chính xác các hàm floor, ceil, round, trunc, format trong Python

Cách lặp qua nhiều list với hàm zip() trong Python

Cách lặp qua nhiều list với hàm zip() trong Python

Top