2014-11-28 16 views
8

Ho un'app Django in cui il mio modello principale ha campi ForeignKey in altre tabelle DB.Django: uso di objects.values ​​() e ottenere dati ForeignKey nel modello

class Bugs(models.Model): 
    bug_id = models.PositiveIntegerField(primary_key=True) 
    bug_severity = models.ForeignKey(Bug_severity,null=True) 
    priority = models.ForeignKey(Priority,null=True) 
    bug_status = models.ForeignKey(Bug_Status,null=True) 
    resolution = models.ForeignKey(Resolution,null=True) 
    etc... 

Tutte le tabelle ForeignKey hanno una funzione unicode che restituisce il nome che si desidera visualizzare nel modello.

class Priority(models.Model): 
    value = models.CharField(max_length=64) 
    sortkey = models.PositiveSmallIntegerField() 
    isactive = models.NullBooleanField() 
    visibility_value_id = models.SmallIntegerField(null=True,blank=True) 

    def __unicode__(self): 
     return self.value 

Nella vista, sono in esecuzione la query come:

bugs = Bugs.objects.filter(active=True).order_by('priority__sortkey','bug_severity__sortke 

Nel modello, posso scorrere attraverso di loro, e visualizzare correttamente il valore ForeignKey.

{% for bug in bugs %} 
    <tr class="bugrow" > 
    <td>{{bug.bug_id}}</td> 
    <td>{{bug.priority}}</td> 
    <td>{{bug.bug_severity}}</td> 
    <td>{{bug.bug_status}}</td> 
    <td>{{bug.resolution}}</td> 

Il problema che sto avendo è che ho bisogno di manipolare i dati Bugs prima di inviarlo al modello, in modo da utilizzare i valori() per restituire un dizionario. Quando passo quel dizionario al modello non mostra alcun campo che punta a un ForeignKey.

Sono abbastanza sicuro che il motivo è che i valori restituiscono solo il valore effettivo del database, quindi non può seguire l'FK.

La domanda è: come posso manipolare i dati che lo inviano al modello e seguire ancora la chiave ForeignKey?

risposta

14

Io uso questo metodo tutto il tempo. Hai ragione. Restituisce solo i valori, quindi devi usare la notazione "__" per ottenere il valore da ForeignKey. Per esempio:

# Get all of the bugs 
bugs = Bugs.objects.filter(
    active=True, 
).order_by(
    'priority__sortkey', 
    'bug_severity__sortkey', 
).values(
    'bug_id', 
    'priority', # Only the pk (id) of the bug priority FK 
    'priority__value', # Equal to bug.priority.value 
    'bug_severity', 
    'bug_severity__some_value', # Equal to bug.priority.some_value 
) 

Ora, nel modello, si fa:

{% for bug in bugs %} 
    <tr class="bugrow"> 
     <td>{{ bug.bug_id }}</td> 
     <td>{{ bug.priority }}</td> 
     <td>{{ bug.priority__value }}</td> 
     <td>{{ bug.bug_severity }}</td> 
     <td>{{ bug.bug_severity__some_value }}</td> 
    </tr> 
{% endfor %} 

Questo è trattato nel QuerySet.values() documentation, vicino alla parte inferiore:

È possibile anche fare riferimento ai campi su modelli correlati con relazioni inverse tramite gli attributi OneToOneField, ForeignKey e ManyToManyField:

Blog.objects.values('name', 'entry__headline') 
[{'name': 'My blog', 'entry__headline': 'An entry'}, 
{'name': 'My blog', 'entry__headline': 'Another entry'}, ...] 
+1

Che ha funzionato perfettamente. Giuro di aver letto 10 volte la documentazione di Queryset.values ​​() cercando di capirlo e di non aver mai letto quel blocco di fondo sulle relazioni FK. – zoidberg

+1

Non sentirti male - l'ho perso più volte quando ho iniziato. Personalmente penso che dovrebbe essere un pezzo in evidenza della documentazione, non un ripensamento. –

Problemi correlati