Django admin change-list optimizing query: select field1, field2 instead of select *

1k views Asked by At

I have a large horizontal table (30 fields) with quite a few foreign keys (each averaging upto 10 fields). While displaying the table in the Django admin, I use select related to optimize and avoid multiple querying. What I am looking for is to ensure that only my list_display entries are retrieved and not all the 30 fields + (foreign keys X 10) fields. Currently a select * on the table + a select * on all the join fields run. Basically, a way to get 'values' at the Django admin level. Thanks.

Edit: An example below:

class X(models.Model):
    x1 = models.IntegerField  # needed for admin display
    x2 = models.TextField     # needed for admin display
    x3 = models.ForeignKey(Y) 
    x4 = models.ForeignKey(Z)
    ...                       # X5 to x30 are not needed for admin display
    X30 = models.Integerfield

    @property
    def y1(self) :
        return self.x3.y1

    @property
    def y2(self):
        return self.x4.z1

class Y(models.Model):
    y1 = models.IntegerField  # needed for admin display
    ...
    y10 = models.IntegerField


class Z(models.Model):
    z1 = models.IntegerField  # needed for admin display
    ...                       # z2 to z10 are not needed for admin display
    z10 = models.IntegerField


**admin.py**
list_display = ['x1', 'x2', 'y1', 'z1']

My problem is when I look at the query generated to display this, it does a select * on X(x1 to x30), and using select_related, it extracts y1 to y10 and z1 to z10, even though I do not need all fields.

This table is heavily used as a CRM and it is currently a showstopper because of the slow query that is generated. There are also blobs and huge varchars, which are not used for the display and still being queried.

Thanks.

1

There are 1 answers

0
Craig Labenz On

Remember that in your list_display block you can always replace x3 with x3_id to use the FK value you already have on hand and not do any extra lookup at all (ditch select_related altogether).

You could then combine that with custom functions for your list_display as outlined here to maybe replace those raw FK integers with hyperlinks to their own admin pages?