2011-02-08 30 views
6
class Log: 
project = ForeignKey(Project) 
msg = CharField(...) 
date = DateField(...) 

Deseo seleccionar las cuatro entradas de registro más recientes donde cada entrada de registro debe tener una clave externa de proyecto única. He prueba la búsqueda de soluciones en google pero ninguno de ellos obras y la documentación de Django no es que muy bueno para las operaciones de búsqueda ..Django: claves externas distintas

he intentado cosas como:

Log.objects.all().distinct('project')[:4] 
Log.objects.values('project').distinct()[:4] 
Log.objects.values_list('project').distinct('project')[:4] 

Pero esto tampoco devuelven nada, o Entradas de registro del mismo proyecto ...

¡Cualquier ayuda sería apreciada!

Respuesta

9

Las consultas no funcionan así, ya sea en el ORM de Django o en el SQL subyacente. Si desea obtener ID únicos, solo puede consultar la ID. Por lo tanto, deberá hacer dos consultas para obtener las entradas de registro reales. Algo como:

id_list = Log.objects.order_by('-date').values_list('project_id').distinct()[:4] 
entries = Log.objects.filter(id__in=id_list) 
+0

Gracias por la respuesta, unfortuatly ID_LIST = Log.objects.order_by ('- date').. Values_list ('project_id') distinta() .. no funciona. No soluciona los distintos. Funciona si elimino order_by() en la cadena, pero luego no está ordenado por fecha ... – mrmclovin

+0

Todavía no funciona ... ¿No hay ayuda en esto? – mrmclovin

+0

prueba pk o usa la función python's reduce() –

3

En realidad, puede obtener los project_ids en SQL. Suponiendo que desea que los identificadores de proyecto único de los cuatro proyectos con las últimas entradas de registro, el SQL se vería así:

SELECT project_id, max(log.date) as max_date 
FROM logs 
GROUP BY project_id 
ORDER BY max_date DESC LIMIT 4; 

Ahora, en realidad se quiere toda la información de registro. En PostgreSQL 8.4 y más tarde se puede utilizar en ventanas funciones, pero eso no quiere trabajar en otras versiones/bases de datos, así que voy a hacerlo de la manera más compleja:

SELECT logs.* 
FROM logs JOIN (
    SELECT project_id, max(log.date) as max_date 
    FROM logs 
    GROUP BY project_id 
    ORDER BY max_date DESC LIMIT 4) as latest 
ON logs.project_id = latest.project_id 
    AND logs.date = latest.max_date; 

Ahora, si usted tiene acceso a sistema de ventanas, que es un poco más limpio (creo que de todos modos), y sin duda más rápido para ejecutar:

SELECT * FROM (
    SELECT logs.field1, logs.field2, logs.field3, logs.date 
     rank() over (partition by project_id 
        order by "date" DESC) as dateorder 
    FROM logs) as logsort 
WHERE dateorder = 1 
ORDER BY logs.date DESC LIMIT 1; 

OK, tal vez no es fácil de entender, pero tomar mi palabra para ella, se ejecuta mundos más rápido en una gran base de datos .

No estoy del todo seguro de cómo se traduce esto en la sintaxis del objeto, o incluso si lo hace. Además, si desea obtener otros datos del proyecto, debe unirse contra la tabla de proyectos.

+0

¡Gracias por la respuesta! Lo intentaré! – mrmclovin

Cuestiones relacionadas