Reputation: 844
I am using Django amdin for one of my data models. I want to display customized values on admin UI for each model. On db, the result of a single query runs as multiple queries on django admin, one for each row I am trying to avoid that.
Here are my models:
class words(models.Model):
word_id=models.AutoField(primary_key=True)
word=models.CharField(max_length=200,unique=True)
def __unicode__(self):
return '%s - %s' % (self.word,self.word_id)
class meanings(models.Model):
id=models.AutoField(primary_key=True)
word_id=models.ForeignKey(words,on_delete=models.CASCADE,db_column='word_id')
meaning=models.CharField(max_length=200)
def __unicode__(self):
return '%s %s %d ' % ( self.spelling_id.spelling,self.meaning,self.id)
For the second model, while loading the page, for each row I saw there are 2 queries running one on words table and other on meanings table. (from debug toolbar)
I tried avoiding that by using the below option.
models.py:
class meanings(models.Model):
meaning_id=models.AutoField(primary_key=True)
word_id=models.ForeignKey(words,on_delete=models.CASCADE,db_column='word_id')
meaning=models.CharField(max_length=200)
admin.py:
def modified_output(self):
cursor = connection.cursor()
cursor.execute("select word,meaning,id from meanings a,words b where a.word_id=b.word_id and meaning_id= "+str(self.id))
row = dictfetchall(cursor)
a=unicode(row[0]['word'])
b=unicode(row[0]['meaning'])
d=(row[0]['id'])
return '%s %s %d ' % ( a,b,d)
meanings.add_to_class("__str__", modified_output)
Now for each row there is only 1 query running. But as the dependency on models have more than 2 tables in join of a query, it will still consume time. So my question is instead of running 1 query for each row, can we have the query result displayed directly for each page.
for example result of the following query on a page:
select * from table ;
instead of
select * from table when id=1;
select * from table when id=2;
.
.
.
Any help is greatly appreciated.Thanks
Upvotes: 1
Views: 1369
Reputation: 599490
You should use the list_select_related
option on the ModelAdmin to tell Django to do a JOIN query.
class MeaningAdmin(admin.ModelAdmin):
list_select_related = ('word_id',)
(Note, you really shouldn't call your FK fields things like word_id
. The field gives access to an actual instance of Word, so it should just be called word
; the underlying db column will automatically be called word_id
.)
Upvotes: 2