Dapatkan rekor terakhir di queryset

89

Bagaimana saya bisa mendapatkan kembali catatan terakhir dalam queryset tertentu?

Stephen
sumber

Jawaban:

81

EDIT: Anda sekarang harus menggunakan Entry.objects.latest('pub_date')


Anda bisa melakukan sesuatu seperti ini, menggunakan reverse():

queryset.reverse()[0]

Juga, waspadalah peringatan ini dari dokumentasi Django:

... perhatikan bahwa reverse()umumnya hanya dipanggil pada QuerySet yang memiliki pengurutan yang ditentukan (misalnya, saat melakukan kueri terhadap model yang menentukan pengurutan default, atau saat menggunakan order_by()). Jika tidak ada urutan seperti itu yang didefinisikan untuk suatu pemberian QuerySet, memanggilnya reverse()tidak memiliki efek nyata (urutannya tidak ditentukan sebelum panggilan reverse(), dan akan tetap tidak ditentukan sesudahnya).

jujule
sumber
2
seperti yang dikatakan dalam dokumen django,: "perhatikan bahwa reverse () pada umumnya hanya harus dipanggil pada QuerySet yang memiliki pengurutan yang ditentukan (misalnya, saat menanyakan model yang mendefinisikan pengurutan default, atau saat menggunakan order_by ()). Jika tidak ada pengurutan seperti itu didefinisikan untuk QuerySet tertentu, memanggil reverse () padanya tidak memiliki efek nyata (urutannya tidak ditentukan sebelum memanggil reverse (), dan akan tetap tidak ditentukan sesudahnya). "
jujule
6
2017 dan jawaban yang diterima sudah usang. Seperti yang ditunjukkan di bawah ini, Anda harus menggunakan queryset.last ().
wobbily_col
137

Django Doc :

latest(field_name=None) mengembalikan objek terbaru dalam tabel, berdasarkan tanggal, menggunakan field_name yang disediakan sebagai field tanggal.

Contoh ini mengembalikan entri terbaru dalam tabel, menurut pub_datebidang:

Entry.objects.latest('pub_date')
Asinox
sumber
5
Ini adalah cara yang tepat untuk melakukannya. Juga, "Jika Meta model Anda menentukan get_latest_by, Anda dapat membiarkan argumen field_name ke latest ()" sesuai dengan dokumen.
Fredrik Möllerstrand
51

Cara termudah untuk melakukannya adalah:

books.objects.all().last()

Anda juga menggunakan ini untuk mendapatkan entri pertama seperti:

books.objects.all().first()
haky_nash
sumber
16
books.objects.last() dan books.objects.first()harus melakukan triknya.
chandan
Ini harus menjadi jawaban yang diterima bersamaan dengan XYZ.objects.first()dan XYZ.objects.last()
slajma
Menurut saya cara Arnaud P lebih tepat. Ini jika tidak salah akan membongkar semua item di DB di mana kemudian menarik yang terakhir menggunakan kueri DB.
Larcho
33

Django> = 1,6

Menambahkan metode QuerySet first () dan last () yang merupakan metode praktis yang mengembalikan objek pertama atau terakhir yang cocok dengan filter. Mengembalikan Tidak Ada jika tidak ada objek yang cocok.

panchicore
sumber
32

Untuk mendapatkan objek pertama:

ModelName.objects.first()

Untuk mendapatkan objek terakhir:

ModelName.objects.last()

Anda bisa menggunakan filter

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

Ini berhasil untuk saya.

Ravi Kumar
sumber
6

Saat queryset sudah habis, Anda dapat melakukan ini untuk menghindari petunjuk db lain -

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

Jangan gunakan try...except....
Django tidak melempar IndexErrordalam kasus ini.
Itu melempar AssertionErroratau ProgrammingError(ketika Anda menjalankan python dengan opsi -O)

jifeng.yin
sumber
1
Dengan asumsi bahwa queryset Anda sudah diurutkan, ini seharusnya menjadi "jawaban teratas", karena ini satu-satunya solusi yang tidak masuk ke database lagi.
David D.
4

Jika menggunakan django 1.6 dan yang lebih baru, itu jauh lebih mudah sekarang karena api baru telah diperkenalkan -

Model.object.earliest()

Ini akan memberikan latest () dengan arah sebaliknya.

ps - Saya tahu pertanyaan lamanya, saya memposting seolah-olah maju seseorang mendarat pada pertanyaan ini, mereka mengetahui fitur baru ini dan akhirnya tidak menggunakan metode lama.

Mutan
sumber
3
dari docs: early () dan latest () memerlukan parameter field_name atau 'get_latest_by' dalam model
panchicore
1

Anda dapat menggunakan Model.objects.last()atau Model.objects.first(). Jika tidakordering yang ditentukan maka queryset diurutkan berdasarkan kunci utama. Jika Anda ingin memesan perilaku queryset maka Anda dapat merujuk ke dua poin terakhir.

Jika Anda berpikir untuk melakukan ini, Model.objects.all().last()untuk mengambil Model.objects.all().first()elemen terakhir dan mengambil elemen pertama dalam queryset atau menggunakanfilters tanpa berpikir dua kali. Kemudian lihat beberapa peringatan di bawah.

Bagian penting yang perlu diperhatikan di sini adalah jika Anda belum menyertakannya ordering dalam model Anda, data dapat disusun dalam urutan apa pun dan Anda akan memiliki elemen terakhir atau pertama acak yang tidak diharapkan.

Misalnya. Misalkan Anda memiliki model bernama Model1yang memiliki 2 kolom iddanitem_count 10 baris memiliki id 1 sampai 10. [Tidak ada urutan yang ditentukan]

Jika Anda mengambil Model.objects.all (). Last () seperti ini, Anda bisa mendapatkan elemen apa pun dari daftar 10 elemen. Ya, Ini acak karena tidak ada pemesanan default.

Jadi apa yang bisa dilakukan?

  1. Anda dapat menentukan orderingberdasarkan bidang atau bidang apa pun pada model Anda. Ini memiliki masalah kinerja juga, Harap periksa juga. Ref: Di sini
  2. ATAU Anda dapat menggunakan order_bysaat mengambil. Seperti ini:Model.objects.order_by('item_count').last()
Roshan Dawande
sumber
-5

Cara termudah, tanpa harus mengkhawatirkan urutan saat ini, adalah dengan mengubah QuerySet menjadi daftar sehingga Anda dapat menggunakan pengindeksan negatif normal Python. Seperti:

list(User.objects.all())[-1]
Josh Ourisman
sumber
2
Ini akan menanyakan SEMUA objek dari DB dan kemudian akan mengambil yang pertama
warvariuc
Poin bagus! Jelas tidak memikirkan yang satu itu. Jawaban .reverse () (saat ini dipilih) adalah cara yang benar untuk pergi!
Josh Ourisman