สิ่งที่ฉันพยายามทำคือ:
ได้รับ 30 ผู้แต่งที่มีคะแนนสูงสุด (
Author.objects.order_by('-score')[:30]
)สั่งผู้เขียนโดย
last_name
ข้อเสนอแนะใด ๆ ?
สิ่งที่ฉันพยายามทำคือ:
ได้รับ 30 ผู้แต่งที่มีคะแนนสูงสุด ( Author.objects.order_by('-score')[:30]
)
สั่งผู้เขียนโดย last_name
ข้อเสนอแนะใด ๆ ?
คำตอบ:
แล้ว
import operator
auths = Author.objects.order_by('-score')[:30]
ordered = sorted(auths, key=operator.attrgetter('last_name'))
ใน Django 1.4 และใหม่กว่าคุณสามารถสั่งซื้อได้โดยระบุหลายช่อง
อ้างอิง: https://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by
order_by (* ช่อง)
ตามค่าเริ่มต้นผลลัพธ์ที่ส่งกลับโดย a QuerySet
จะเรียงลำดับตามลำดับทูเปิลที่กำหนดโดยordering
ตัวเลือกใน Meta ของโมเดล คุณสามารถแทนที่สิ่งนี้บนพื้นฐานต่อ QuerySet โดยใช้order_by
วิธีการ
ตัวอย่าง:
ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]
ผลลัพธ์ข้างต้นจะเรียงscore
ลำดับจากlast_name
มากไปหาน้อยจากน้อยไปมาก เครื่องหมายลบด้านหน้า"-score"
หมายถึงลำดับจากมากไปหาน้อย ลำดับจากน้อยไปมากเป็นนัย
lambda x: x.last_name
? สั้นกว่าละเอียดกว่าและไม่ต้องนำเข้าใด ๆ
ฉันแค่อยากจะแสดงให้เห็นว่าโซลูชันในตัว (เฉพาะ SQL) ไม่ใช่โซลูชันที่ดีที่สุดเสมอไป ตอนแรกฉันคิดว่าเนื่องจากQuerySet.objects.order_by
วิธีการของ Django ยอมรับข้อโต้แย้งหลายข้อคุณจึงสามารถเชื่อมโยงได้อย่างง่ายดาย:
ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]
แต่มันไม่ได้ผลตามที่คุณคาดหวัง ในประเด็นอันดับแรกคือรายชื่อประธานาธิบดีเรียงตามคะแนน (เลือก 5 อันดับแรกเพื่อให้อ่านง่ายขึ้น):
>>> 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 ซึ่งให้บริการคน 5 อันดับแรกอย่างแม่นยำเรียงตาม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)
และตอนนี้การorder_by
โทรรวม:
>>> 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)
อย่างที่คุณเห็นมันเป็นผลลัพธ์เดียวกันกับผลลัพธ์แรกซึ่งหมายความว่ามันไม่ได้ผลอย่างที่คุณคาดหวัง
นี่คือวิธีที่ช่วยให้มีความสัมพันธ์สำหรับคะแนนที่ถูกตัดออก
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')
คุณอาจได้ผู้เขียนมากกว่า 30 คนใน top_authors ด้วยวิธีนี้และในmin(30,author_count)
กรณีที่คุณมีผู้เขียนน้อยกว่า 30 คน