2010-03-09 9 views
69

lo que estoy tratando de hacer es lo siguiente:¿Buenas maneras de ordenar un conjunto de preguntas? - Django

  • conseguir los 30 autores con mayor puntuación (Author.objects.order_by('-score')[:30])

  • para los autores por last_name


¿Alguna sugerencia?

+2

@RH: entonces, ¿qué hay de comprobar la respuesta de AlexMartelli como la solución correcta?(No es que necesite más representante, a menos que persiga a ese tipo de Skeet ...) – PaulMcG

+0

Simple y al grano. Esto funciona. ¡Gracias! – Shilpa

Respuesta

125

¿Qué hay de

import operator 

auths = Author.objects.order_by('-score')[:30] 
ordered = sorted(auths, key=operator.attrgetter('last_name')) 

En Django 1.4 y posteriores puede pedir proporcionando múltiples campos.
Referencia: https://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by

order_by (* campos)

Por defecto, los resultados devueltos por una QuerySet están ordenados por la ordenación tupla dada por la opción ordering en Meta del modelo. Puede anular esto en base a QuerySet utilizando el método order_by.

Ejemplo:

ordered_authors = Author.objects.order_by('-score', 'last_name')[:30] 

El resultado anterior se ordenará por score descendente, a continuación, por last_name ascendente. El signo negativo al frente de "-score" indica un orden descendente. El orden ascendente está implícito.

+0

@Alex: grazie alex! Eso fue genial, ¡me voy a leer sobre el módulo de operador! – RadiantHex

+3

¿Es esto más eficiente que Author.objects.order_by ('- score', 'last_name') [: 30]? –

+4

@Brian - si por "más eficiente" quiere decir "más correcto", entonces sí, es. :) Su solución mantiene a los autores bastante ordenados por puntaje, y solo alfabetiza a los autores con el mismo puntaje (que es cómo funcionan las teclas secundarias). Alex muestra cómo tomar los resultados y luego les aplica un orden de clasificación completamente diferente (usando key = operator.attrgetter para definir una expresión de clave por objeto), que es lo que solicitó OP. – PaulMcG

3

Aquí hay una manera que permite lazos para el puntaje de corte.

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') 

Usted puede obtener más de 30 autores en top_authors esta manera y el min(30,author_count) está allí en caso que usted tiene menos de 30 autores.

9

Solo quería ilustrar que las soluciones integradas (solo SQL) no siempre son las mejores. Al principio pensé que debido a que el método de Django QuerySet.objects.order_by acepta varios argumentos, que podría fácilmente encadenarlos:

ordered_authors = Author.objects.order_by('-score', 'last_name')[:30] 

embargo, no funciona como era de esperar. El caso en cuestión, en primer lugar es una lista de presidentes ordenados según puntuación (la selección de la parte superior 5 para facilitar la lectura):

>>> 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) 

Utilizando la solución de Alex Martelli que proporciona precisión los 5 mejores personas Weaver 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) 

Y ahora el combinado order_by llamada:

>>> 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) 

como se puede ver que es el mismo resultado que la primera, lo que significa que no funciona como lo haría un correo xpect.

+10

Tu resultado # 3 está ordenando descendentes por puntaje y luego por apellido IFF todos los objetos tienen el mismo puntaje. El problema es que ninguno de los objetos del conjunto de resultados tiene el mismo puntaje, por lo que solo el '-score' está afectando al orden de clasificación. Intente establecer la puntuación de 3 autores en 487 y ejecute la # 3 nuevamente. – istruble

+0

Sí, entiendo eso. Realmente solo quería ilustrar que las soluciones integradas (solo SQL) no siempre son las mejores. – jathanism

+0

+1 Buen ejemplo de la cláusula contraria a la intuición ORDER BY – PaulMcG

Cuestiones relacionadas