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

Desidero selezionare le quattro voci di registro più recenti in cui ogni voce di registro deve avere una chiave esterna di progetto univoca. Sono cerca le soluzioni su google ricerca, ma nessuno di loro opere e la documentazione Django non è che molto buona per la ricerca ..Django: Chiavi esterne distinte

ho provato cose come:

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

Ma questa sia nulla di ritorno o Entra voci dello stesso progetto ..

Qualsiasi aiuto sarebbe apprezzato!

risposta

9

Le query non funzionano in questo modo: nell'ORM di Django o nell'SQL sottostante. Se si desidera ottenere ID univoci, è possibile richiedere solo l'ID. Quindi dovrai fare due query per ottenere le voci del registro effettive. Qualcosa di simile:

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

Grazie per la risposta, unfortuatly ID_LIST = Log.objects.order_by ('- la data').. Values_list ('project_id') distinti() .. non funziona. Non risolve i distinti. Funziona se rimuovo order_by() nella catena, ma poi non è ordinato per data ... – mrmclovin

+0

Ancora non funziona .. Nessun aiuto su questo? – mrmclovin

+0

prova pk o usa la funzione reduce() di python –

3

In realtà, è possibile ottenere i project_ids in SQL. Supponendo che si desidera gli ID di progetto unici per i quattro progetti con le ultime voci di registro, SQL sarebbe simile a questa:

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

Ora, in realtà si vuole tutte le informazioni di log. In PostgreSQL 8.4 e versioni successive è possibile utilizzare le funzioni di windowing, ma che non funziona su altre versioni/basi di dati, quindi mi farlo nel modo più complesso:

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; 

Ora, se si dispone di accesso a funzioni di windowing, è un po 'più ordinato (credo comunque), e certamente più veloce da eseguire:

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, forse non è più facile da capire, ma prendere la mia parola per esso, viene eseguito mondi più veloce su un database di grandi dimensioni .

Non sono completamente sicuro di come ciò si traduca nella sintassi dell'oggetto, anche se lo fa. Inoltre, se si desidera ottenere altri dati di progetto, è necessario unirsi alla tabella dei progetti.

+0

Grazie per la risposta! Lo proverò! – mrmclovin