Many queries from django foreignkey fields

I drove Django all the time while coding the internal website in record time, but now I notice that something is very inefficient with my ForeignKeys in the model.

I have a model that has 6 ForeignKeys, which are basically lookup tables. When I request all the objects and display them in the template, it launches about 10 requests per element. Here is some code that should explain this better:

class Website(models.Model):
    domain_name = models.CharField(max_length=100)
    registrant = models.ForeignKey('Registrant')
    account = models.ForeignKey('Account')
    registrar = models.ForeignKey('Registrar')
    server = models.ForeignKey('Server', related_name='server')
    host = models.ForeignKey('Host')
    target_server = models.ForeignKey('Server', related_name='target')

class Registrant(models.Model):
    name = models.CharField(max_length=100)

... and 5 more simple tables. There are 155 entries on the site, and in the view I use:

Website.objects.all()

It finishes executing 1544 queries. In the template, I use all external fields, for example:

<span class="value">Registrant:</span> <a href="/filter/registrant/{{ website.registrant.id }}">{{ website.registrant.name }}</a><br />

So, I know that it will run a lot of requests ... but it seems like this is excessive. This is normal? Should I do it like this?

Django, , , - . .

+5
1

select_related function,

Website.objects.select_related()

, , . Django ,

# one database query
website = Website.objects.get(id=123)

# first time account is referenced, so another query
print website.account.username 

# account has already been loaded, so no new query
print website.account.email_address

# first time registrar is referenced, so another query
print website.registrar.name

.. , , , . ,

# one database query with a join and all foreign keys followed
website = Website.objects.select_related().get(id=123)

# no additional query is needed because the data is already loaded
print website.account.username
print website.account.email_address
print website.registrar.name
+5

All Articles