yapmaya çalıştığım şey şudur:
en yüksek puana sahip 30 Yazarı al (
Author.objects.order_by('-score')[:30]
)yazarları sırala
last_name
Baska öneri?
yapmaya çalıştığım şey şudur:
en yüksek puana sahip 30 Yazarı al ( Author.objects.order_by('-score')[:30]
)
yazarları sırala last_name
Baska öneri?
Yanıtlar:
Ne dersin
import operator
auths = Author.objects.order_by('-score')[:30]
ordered = sorted(auths, key=operator.attrgetter('last_name'))
Django 1.4 ve daha yeni sürümlerde, birden çok alan sağlayarak sipariş verebilirsiniz.
Referans: https://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by
order_by (* alanlar)
Varsayılan olarak, a tarafından döndürülen sonuçlar , modelin QuerySet
Meta'sındaki ordering
seçenek tarafından verilen sıralama dizisine göre sıralanır . order_by
Yöntemi kullanarak bunu QuerySet başına temelinde geçersiz kılabilirsiniz .
Misal:
ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]
Yukarıdaki sonuç score
azalan, sonra last_name
artan şekilde sıralanacaktır . Önündeki eksi işareti "-score"
azalan sırayı gösterir. Artan sıra ima edilir.
lambda x: x.last_name
? Daha kısa, daha ayrıntılı ve içe aktarmaya gerek yok.
Sadece yerleşik çözümlerin (yalnızca SQL) her zaman en iyisi olmadığını göstermek istedim. İlk başta, Django'nun QuerySet.objects.order_by
yöntemi birden fazla argümanı kabul ettiği için bunları kolayca zincirleyebileceğinizi düşündüm :
ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]
Ancak beklediğiniz gibi çalışmıyor. Örnek olarak, ilk önce puana göre sıralanmış başkanların bir listesidir (daha kolay okumak için ilk 5'i seçin):
>>> 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)
Alex Martelli'nin en iyi 5 kişiyi doğru şekilde sıralayan çözümünü kullanarak 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)
Ve şimdi birleşik order_by
çağrı:
>>> 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)
Gördüğünüz gibi, birincisi ile aynı sonuç, yani beklediğiniz gibi çalışmıyor.
İşte kesme puanı için eşitliğe izin veren bir yol.
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')
Bu şekilde top_authors kategorisinde 30'dan fazla yazar alabilirsiniz ve min(30,author_count)
30'dan az yazara sahip olmanız durumunda orada olur.