2010-08-14 12 views
8

Ho il campo "sottomissione" che ha un utente e un problema. Come posso ottenere un risultato di ricerca SQL che fornirà un elenco di un solo risultato per coppia di problemi utente?Selezione query Django distinta per coppie di campi

I modelli sono come questo:

class Problem(models.Model): 
    title = models.CharField('Title', max_length = 100) 
    question = models.TextField('Question') 

class Submission(models.Model): 
    user = models.ForeignKey(User) 
    problem = models.ForeignKey(Problem) 
    solution = models.CharKey() 
    time = models.DateTimeField('Time', auto_now_add=True) 
+0

Cosa intendi per "campo che ha un utente e un problema"? Stai parlando di modelli Django? Pubblica il codice pertinente. –

+0

I modelli sono come questo: Problema: titolo, in discussione Submission: problema (ForeignKey), utente (ForeignKey), contenuti Utente: Aut utente Diamo p1 Supponiamo, p2 due problemi e U1, U2 sono due utenti U1 ha due sottomissioni s1, s2 per p1 e uno (s3) per p2 e u2 ne hanno uno per p1 (s4), due per p2 (s5, s6) Quindi voglio un risultato queryset come questo: s2, s3, s4, s6 ie trascurano i vecchi con lo stesso problema utente s2, s3, – crodjer

risposta

3

Update 2:

(Dopo aver letto i commenti di OP) Suggerisco l'aggiunta di un nuovo modello per tenere traccia l'ultimo di presentazione. Chiamalo LatestSubmission.

class LatestSubmission(models.Model): 
    user = models.ForeignKey(User)  
    problem = models.ForeignKey(Problem) 
    submission = models.ForeignKey(Submission) 

È quindi possibile

  1. esclusione Submission.save() per creare/aggiornare la voce in LatestSubmission ogni volta che un utente inserisce una nuova soluzione per un problema
  2. allegare una funzione che fa la stessa cosa a un adatto signal.

tale che LatestSubmission conterrà una riga per ogni combinazione problema-user-presentazione indicando l'ultimo di presentazione per il problema da ogni utente. Una volta che avete questo sul posto si può sparare una singola query:

LatestSubmission.objects.all().order_by('problem') 

Aggiornamento:

Dal momento che l'OP ha pubblicato il codice di esempio, la soluzione può essere modificato come segue:

for user in User.objects.all(): # Get all users 
    user.submission_set.latest('time') # Pick the latest submission based on time. 

risposta originale

In assenza di qualsiasi data/ora basato i criteri per decidere quale è "più vecchio" o "più recente", è possibile utilizzare la chiave primaria (id) di Submission per "trascurare quelli vecchi".

for user in User.objects.all(): # Get all users 
    user.submission_set.latest('id') # Pick the latest submission by each user. 
+0

Ho aggiunto i dettagli del modello al mio problema. Questo mi darà solo il set di query dell'ultima submission da parte di un utente e quello che voglio è l'ultimo risultato per tutti i problemi. Voglio eseguire un comando sql sul campo di invio e ottenere l'elenco degli invii ordinati per tempo di invio e includerò solo un risultato se ci sono più di un invio di uno stesso utente in un problema. – crodjer

+0

@Rohan Jain: non sono sicuro che sia possibile farlo con _one_ query SQL data la struttura del modello _current_. Mi piacerebbe sapere se qualcun altro qui può trovare una risposta adeguata. –

+0

lo sto facendo ora aggiungendo un campo booleano is_latest per l'invio ..... grazie per il tuo aiuto :) – crodjer

12

Prova questo:

distinct_users_problems = Submission.objects.all().values("user", "problem").distinct() 

che vi darà un elenco di dicts come questo:

[{'problem': 1, 'user': 1}, {'problem': 2, 'user': 1}, {'problem': 3, 'user': 1}] 

contenente tutte le coppie distinte.

In realtà risulta nella normale query SQL SELECT DISTINCT.

Problemi correlati