Ho una classe ModelAdmin
che include un campo chiave esterna nel suo list_display
. Ma la pagina di elenco amministratore per quel modello sta facendo centinaia di query, una query per riga per ottenere i dati dall'altra tabella invece di un join (select_related()
).Perché l'admin di Django list_select_related non funziona in questo caso?
I documenti Django indicate è possibile aggiungere list_select_related = True
come attributo a ModelAdmin per farlo andare via, ma non sembra funzionare affatto per me. This SO question sembra dare un problema simile, ma la sua risoluzione non è chiara, e non funziona nel mio caso.
Ecco una versione ridotta del mio modello e il modello di amministrazione:
class Device(models.Model):
serial_number = models.CharField(max_length=80, blank=True, unique=True)
label = models.CharField(max_length=80, blank=True)
def __str__(self):
s = str(self.serial_number)
if self.label:
s += ': {0}'.format(self.label)
return s
class Event(models.Model):
device = models.ForeignKey(Device, null=True)
type = models.CharField(max_length=40, null=False, blank=True, default='')
class EventAdmin(admin.ModelAdmin):
list_display = ('__str__', 'device')
list_select_related = True
Tuttavia, aggiungendo che list_selected_related = True
non ha cambiato nulla. Ho ancora un sacco di domande come questo invece di uno SQL uniscono:
Tutte le idee perché l'amministratore Django sembra ignorare i miei list_select_related e fare query N? Sto usando Python 2.7 e Django 1.3.3.
Grazie! Il 'nullo = Vero' sulla chiave esterna stava sicuramente impedendo a selected_related di fare la sua cosa. Immagino che se avessi seguito i [documenti] (https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.select_related) fino in fondo, Avrei visto che: "Nota che, per impostazione predefinita, select_related() non segue le chiavi esterne che hanno null = True" –
Fuori interesse, sai perché 'list_select_related = True' non è l'impostazione predefinita per il Django amministratore? Sembrerebbe un default molto più sensato. (Capisco perché di default 'select_related()' non segue chiavi esterne che hanno null = True, perché potrebbe essere un problema di prestazioni, ma mi chiedo a proposito di 'list_select_related' in altri casi.) –
In Django> = 1.6 il metodo è ora denominato 'get_queryset'. – TAH