Matt Wilson
Matt Wilson

Reputation: 49

In Django, optimize performance when using a foreign key's attribute in the __str__method

The implementation of DocumentDetail's str method works, but is slows everything down by running a bunch of extra queries when I try to use it views, forms, etc. Does anyone know a way around this?

models.py

class Document(models.Model):
    description = models.CharField(max_length=50)

    def __str__(self):
        return self.description

class DocumentDetail(models.Model):
    document = models.ForeignKey(Document, on_delete=models.CASCADE)
    detail = models.CharField(max_length=50)

    def __str__(self):
        return self.document.description

Upvotes: 1

Views: 780

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476493

You should load the DocumentDetail with the Document. You can do this with .select_related(…) [Django-doc].

Indeed, we can for example load the DocumentDetail and load the document itself together with the DocumentDetails with:

DocumentDetail.objects.select_related('document').get(pk=1)

This will make a LEFT OUTER JOIN and thus load both the DocumentDetail and the Document in the same query.

We can also fetch all DocumentDetails with the related Documents with:

DocumentDetail.objects.select_related('document')  # all DocumentDetails

In views/modelviewsets, etc. where you need to call str(…) on the DocumentDetail, you thus should rewrite the queries to load the related Document in the same query.

Upvotes: 2

Related Questions