2009-05-10 10 views
48

tengo una lista de objetos ¿Cómo puedo ejecutar una consulta para dar el valor máximo de un campo:¿Cómo hacer SELECCIONAR MAX en Django?

Estoy usando este código:

def get_best_argument(self): 
    try: 
     arg = self.argument_set.order_by('-rating')[0].details 
    except IndexError: 
     return 'no posts' 
    return arg 

calificación es un número entero

Respuesta

97

Ver this. Su código sería algo como lo siguiente:

from django.db.models import Max 
# Generates a "SELECT MAX..." statement 
Argument.objects.all().aggregate(Max('rating')) 

Si ya ha llegado la lista de la base de datos, entonces usted haría algo como esto:

from django.db.models import Max 
args = Argument.objects.all() 
# Calculates the maximum out of the already-retrieved objects 
args.aggregate(Max('rating')) 

Esto no se ha probado por lo que puede haber cometido un error en alguna parte, pero ahí lo tienes.

+0

typo: "import Avg" -> "import Max"? – Tom

+0

Sí, hice ese cambio en mi código – Johnd

+4

Necesito el objeto de argumento actual que tiene ese valor Máx., Así que puedo imprimir el campo de detalles. La llamada args.aggregate (Max ('calificación')) solo devuelve la calificación más alta. Estoy buscando el arg con la calificación más alta. – Johnd

37

He probado esto para mi proyecto, se encuentra el máximo/mínimo en O (n) tiempo:

from django.db.models import Max 

#Find the maximum value of the rating, and then get the record with that rating. Notice the double underscores in rating__max 
max_rating = App.objects.all().aggregate(Max('rating'))['rating__max'] 
return App.objects.get(rating = max_rating) 

Esto está garantizado para conseguir que uno de los elementos máximo y de manera eficiente, en lugar de la clasificación de la toda la mesa y obtener la parte superior (alrededor de O (nlogn)).

+4

Big-O a veces no se cumple en la práctica, especialmente para n más pequeños, donde importan los coeficientes y la implementación. Su código está en python/django, que está compilado en bytecode y puede o no estar optimizado. La base de datos probablemente esté escrita en un lenguaje optimizado y compilado a las instrucciones de la máquina. Además, la base de datos no tiene un motivo real para ordenar, si la función solo busca un valor máximo. Me gustaría ver los datos de tiempo antes de que me sienta cómodo usando el código de compilación manual sobre una función de base de datos integrada. – benevolentprof

46

Django también tiene la función 'latest(field_name = None)' que encuentra la última entrada (valor máximo). No solo funciona con campos de fecha sino también con cadenas y números enteros.

Se puede dar el nombre del campo cuando se llama a esa función:

max_rated_entry = YourModel.objects.latest('rating') 
return max_rated_entry.details 

O ya se puede dar ese nombre de campo en sus modelos de metadatos:

from django.db import models 

class YourModel(models.Model): 
    #your class definition 
    class Meta: 
     get_latest_by = 'rating' 

Ahora puede llamar 'última () 'sin ningún parámetro:

max_rated_entry = YourModel.objects.latest() 
return max_rated_entry.details 
+3

Esta es una gran manera de usar 'latest()'. Si necesita el registro con el valor mínimo, puede usar 'early()'. – SaeX

+1

'latest()' y 'earliest()' funciona también con el campo sin fecha, pero es un efecto secundario de la implementación. Debe usar ' .order_by (''). First()' o ' .order_by ('').last() 'para asegurarse de que su código seguirá funcionando incluso si los desarrolladores de Django cambian la implementación' latest() 'y' first() 'para trabajar solo con campos de fecha. – mrnfrancesco

Cuestiones relacionadas