apa yang saya coba lakukan adalah ini:
dapatkan 30 Penulis dengan skor tertinggi (
Author.objects.order_by('-score')[:30]
)pesan penulis menurut
last_name
Ada saran?
apa yang saya coba lakukan adalah ini:
dapatkan 30 Penulis dengan skor tertinggi ( Author.objects.order_by('-score')[:30]
)
pesan penulis menurut last_name
Ada saran?
Jawaban:
Bagaimana dengan
import operator
auths = Author.objects.order_by('-score')[:30]
ordered = sorted(auths, key=operator.attrgetter('last_name'))
Dalam Django 1.4 dan yang lebih baru Anda dapat memesan dengan menyediakan banyak bidang.
Referensi: https://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by
order_by (* bidang)
Secara default, hasil yang dikembalikan oleh a QuerySet
diurutkan oleh tupel pemesanan yang diberikan oleh ordering
opsi dalam model Meta. Anda dapat menimpa ini pada basis per-QuerySet dengan menggunakan order_by
metode ini.
Contoh:
ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]
Hasil di atas akan diurutkan dengan score
turun, lalu last_name
naik. Tanda negatif di depan "-score"
menunjukkan urutan menurun. Urutan menaik tersirat.
lambda x: x.last_name
? Lebih pendek, lebih bertele-tele dan tidak perlu diimpor.
Saya hanya ingin mengilustrasikan bahwa solusi bawaan (hanya SQL) tidak selalu yang terbaik. Pada awalnya saya berpikir karena QuerySet.objects.order_by
metode Django menerima banyak argumen, Anda dapat dengan mudah merangkainya:
ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]
Tapi, itu tidak berfungsi seperti yang Anda harapkan. Contoh kasus, pertama adalah daftar presiden yang diurutkan berdasarkan skor (memilih 5 teratas agar lebih mudah dibaca):
>>> auths = Author.objects.order_by('-score')[:5]
>>> for x in auths: print x
...
James Monroe (487)
Ulysses Simpson (474)
Harry Truman (471)
Benjamin Harrison (467)
Gerald Rudolph (464)
Menggunakan solusi Alex Martelli yang secara akurat memberikan 5 orang teratas yang diurutkan berdasarkan last_name
:
>>> for x in sorted(auths, key=operator.attrgetter('last_name')): print x
...
Benjamin Harrison (467)
James Monroe (487)
Gerald Rudolph (464)
Ulysses Simpson (474)
Harry Truman (471)
Dan sekarang order_by
panggilan gabungan :
>>> myauths = Author.objects.order_by('-score', 'last_name')[:5]
>>> for x in myauths: print x
...
James Monroe (487)
Ulysses Simpson (474)
Harry Truman (471)
Benjamin Harrison (467)
Gerald Rudolph (464)
Seperti yang Anda lihat, ini adalah hasil yang sama dengan yang pertama, artinya tidak berfungsi seperti yang Anda harapkan.
Inilah cara yang memungkinkan ikatan untuk skor cut-off.
author_count = Author.objects.count()
cut_off_score = Author.objects.order_by('-score').values_list('score')[min(30, author_count)]
top_authors = Author.objects.filter(score__gte=cut_off_score).order_by('last_name')
Anda bisa mendapatkan lebih dari 30 penulis di top_authors dengan cara ini dan min(30,author_count)
apakah ada jika Anda memiliki kurang dari 30 penulis.