Nhận bản ghi cuối cùng trong bộ truy vấn


89

Làm cách nào để truy xuất bản ghi cuối cùng trong một bộ truy vấn nhất định?

Câu trả lời:


81

CHỈNH SỬA: Bây giờ bạn phải sử dụng Entry.objects.latest('pub_date')


Bạn có thể đơn giản làm điều gì đó như thế này, sử dụng reverse():

queryset.reverse()[0]

Ngoài ra, hãy cẩn thận cảnh báo này từ tài liệu Django:

... lưu ý rằng reverse()thường chỉ được gọi trên QuerySet có thứ tự xác định (ví dụ: khi truy vấn đối với mô hình xác định thứ tự mặc định hoặc khi sử dụng order_by()). Nếu không có thứ tự nào như vậy được xác định cho một thứ nhất định QuerySet, việc gọi reverse()nó sẽ không có tác dụng thực sự (thứ tự không được xác định trước khi gọi reverse()và sẽ vẫn không được xác định sau đó).


2
như đã nói trong tài liệu django,: "lưu ý rằng reverse () nói chung chỉ nên được gọi trên QuerySet có thứ tự xác định (ví dụ: khi truy vấn mô hình xác định thứ tự mặc định hoặc khi sử dụng order_by ()). Nếu không thứ tự như vậy được xác định cho một QuerySet nhất định, việc gọi reverse () trên nó không có tác dụng thực sự (thứ tự không được xác định trước khi gọi reverse () và sẽ vẫn không được xác định sau đó). "
jujule

6
2017 và các câu trả lời được chấp nhận hiện đã lỗi thời. Như hình dưới đây, bạn nên sử dụng queryset.last ().
wobbily_col

134

Django Doc :

latest(field_name=None) trả về đối tượng mới nhất trong bảng, theo ngày, sử dụng field_name được cung cấp làm trường ngày.

Ví dụ này trả về Mục nhập mới nhất trong bảng, theo pub_datetrường:

Entry.objects.latest('pub_date')

5
Đây là cách gọn gàng để làm điều đó. Ngoài ra, "Nếu Meta của mô hình của bạn chỉ định get_latest_by, bạn có thể bỏ đối số field_name thành mới nhất ()" theo tài liệu.
Fredrik Möllerstrand Ngày

50

Cách đơn giản nhất để làm điều đó là:

books.objects.all().last()

Bạn cũng sử dụng điều này để có được mục nhập đầu tiên như vậy:

books.objects.all().first()

16
books.objects.last() books.objects.first()nên thực hiện thủ thuật.
chandan

Đây phải là câu trả lời được chấp nhận cùng với XYZ.objects.first()XYZ.objects.last()
slavejma

Tôi nghĩ cách của Arnaud P là thích hợp hơn cả. Điều này nếu không nhầm sẽ giải nén tất cả các mục trong DB nơi mà sau này sẽ lấy truy vấn cuối cùng bằng cách sử dụng DB.
Larcho

33

Django> = 1,6

Đã thêm các phương thức QuerySet first () và last () là các phương thức tiện lợi trả về đối tượng đầu tiên hoặc cuối cùng phù hợp với bộ lọc. Trả về Không nếu không có đối tượng nào phù hợp.


32

Để lấy đối tượng Đầu tiên:

ModelName.objects.first()

Để lấy các đối tượng cuối cùng:

ModelName.objects.last()

Bạn có thể sử dụng bộ lọc

ModelName.objects.filter(name='simple').first()

Điều này làm việc cho tôi.


6

Khi bộ truy vấn đã hết, bạn có thể làm điều này để tránh một gợi ý db khác -

last = queryset[len(queryset) - 1] if queryset else None

Không sử dụng try...except....
Django không ném IndexErrorvào trường hợp này.
Nó ném AssertionErrorhoặc ProgrammingError(khi bạn chạy python với tùy chọn -O)


1
Giả sử rằng bộ truy vấn của bạn đã được sắp xếp, đây phải là "câu trả lời hàng đầu", vì đó là giải pháp duy nhất không đánh lại cơ sở dữ liệu.
David D.

4

Nếu sử dụng django 1.6 trở lên, việc này sẽ dễ dàng hơn nhiều khi api mới được giới thiệu -

Model.object.earliest()

Nó sẽ cho kết quả mới nhất () với hướng ngược lại.

ps - Tôi biết câu hỏi cũ của nó, tôi đăng bài như thể sẽ có ai đó tiếp cận câu hỏi này, họ sẽ biết tính năng mới này và không kết thúc bằng phương pháp cũ.


3
từ tài liệu: sớm nhất () và mới nhất () yêu cầu hoặc là một tham số field_name hoặc 'get_latest_by' trong mô hình
panchicore

1

Bạn có thể sử dụng Model.objects.last()hoặc Model.objects.first(). Nếu không có nào orderingđược xác định thì tập truy vấn được sắp xếp dựa trên khóa chính. Nếu bạn muốn đặt hàng truy vấn hành vi thì bạn có thể tham khảo hai điểm cuối cùng.

Nếu bạn đang suy nghĩ để làm điều này, Model.objects.all().last()để truy xuất cuối cùng và Model.objects.all().first()truy xuất phần tử đầu tiên trong bộ truy vấn hoặc sử dụngfilters mà không cần suy nghĩ thứ hai. Sau đó, hãy xem một số lưu ý dưới đây.

Phần quan trọng cần lưu ý ở đây là nếu bạn chưa đưa bất kỳ phần tử nào orderingvào mô hình của mình, dữ liệu có thể theo bất kỳ thứ tự nào và bạn sẽ có phần tử cuối cùng hoặc phần tử đầu tiên ngẫu nhiên không được mong đợi.

Ví dụ. Giả sử bạn có một mô hình được đặt tên Model1có 2 cột iditem_count 10 hàng có id từ 1 đến 10. [Không có thứ tự nào được xác định]

Nếu bạn tìm nạp Model.objects.all (). Last () như thế này, Bạn có thể lấy bất kỳ phần tử nào từ danh sách 10 phần tử. Có, nó là ngẫu nhiên vì không có thứ tự mặc định.

Vậy thì cái gì có thể làm được?

  1. Bạn có thể xác định orderingdựa trên bất kỳ trường nào hoặc các trường trên mô hình của bạn. Nó cũng có vấn đề về hiệu suất, Vui lòng kiểm tra điều đó. Tham khảo: Tại đây
  2. HOẶC bạn có thể sử dụng order_bytrong khi tìm nạp. Như thế này:Model.objects.order_by('item_count').last()

-5

Cách đơn giản nhất, mà không phải lo lắng về thứ tự hiện tại, là chuyển QuerySet thành một danh sách để bạn có thể sử dụng lập chỉ mục phủ định thông thường của Python. Như vậy:

list(User.objects.all())[-1]

2
Điều này sẽ truy vấn tất cả các đối tượng từ DB và sau đó sẽ đi đầu tiên
warvariuc

Điểm tốt! Rõ ràng là không nghĩ rằng một trong những thông qua. Câu trả lời .reverse () (hiện được chọn) là cách thích hợp để sử dụng!
Josh Ourisman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.