2011-11-11 19 views
7

Ho 4 modelli e voglio recuperare un join tra di loroDjango invertire relazione con select_related

ModelA

class ModelA(models.Model): 
    product = models.ForeignKey(ModelB) 
    group = models.ForeignKey(Group) 

ModelB

class ModelB(models.Model): 
    title = models.CharField() 

ModelC

class ModelC(models.Model): 
    product = models.ForeignKey(ModelB) 
    group = models.ForeignKey(ModelD) 

ModelD

class ModelD(models.Model): 
    name = models.CharField() 

ora voglio tutti i miei Modela oggetti uniti con ModelB, ModelC e ModelD In SQL questo è abbastanza facile cosa da fare. Basta creare join tra i tavoli. Con Django ORM sono bloccato perché posso solo fare una relazione in avanti.

sto facendo questo

ModelA.objects.all().select_related(product) 

Ma non posso aderire ModelC ho già letto this article, ma io non voglio anello sopra la mia lista grande, per fare una cosa semplice! E voglio colpire il database solo una volta.

Sto usando l'ultima versione di Django e spero che ci sia già una soluzione a questo, di cui non sono a conoscenza.

Grazie.

+0

Hai provato qualcosa del genere: 'ModelA.objects.all().select_related ('product', 'product__modelc', 'product__modelc__group') ' ? Non postare questo come risposta perché non sono assolutamente sicuro se sarebbe quello che vuoi. –

+1

@bildja: 'select_related' fa * not * supporta gli attraversamenti. –

risposta

8

Vedere i documenti su prefetch_related. È solo per il momento, ma colpirà con Django 1.4. Se puoi aspettare o puoi correre sul tronco. Sarai in grado di usarlo.

Nel frattempo, è possibile provare django-batch-select. Ha essenzialmente lo stesso scopo.

3

Modifica: dopo aver riletto il problema, la soluzione non è così semplice.

Il docs dicono:

select_related è limitato a relazioni a valore singolo - un uno-a-chiave e stranieri.

Django 1.4 querysets avrà il metodo prefetch_related, che è consigliabile leggere. Sembra che tu non sia in grado di farlo in una singola query, ma potresti essere in grado di farlo in 2 o 3. Dovresti assolutamente dare un'occhiata e aggiornare alla versione di sviluppo se ne hai davvero bisogno.

Se non è possibile utilizzare la versione di sviluppo e non può attendere 1.4, django supporta anche custom SQL queries.

+0

corretto. 'prefetch_related' non fa tutto in una singola query come select_related. Semplicemente, non c'è modo di farlo. È pensato per il problema delle query n + 1 in cui il looping degli elementi correlati genera una query per ogni ciclo. Al contrario, esegue prima una singola query per la relazione e quindi memorizza il risultato in cache in un secondo momento. –

Problemi correlati