7 Ways to Optimize Access to Database in Django

Here are a few tips about database access optimization.

Picture of Nsikak Imoh, author of Macsika Blog
A blank white background with the text 7 Ways to Optimize Access to Database in Django
A blank white background with the text 7 Ways to Optimize Access to Database in Django

This post is part of the tutorial series titled Learn to Use Django with FastAPI Frameworks

Table of Content

Most developers who work with Django usually miss these simple optimizations when accessing the database.

For most people currently working on a project, I do not recommend you jump into your code base and start refactoring using these tips.

Recommendably, for existing code, it is always a better idea to profile your queries first with a tool like Django Debug Toolbar for instance, then you can get an idea of the sort of optimizations to do.

However, the tips I will share in this post are very easy to start applying when you choose to, so keep them in mind when writing new code!

Here are a few tips about database access optimization.

1. Perform Bulk Insert on Many to Many Fields in Django

Here is a more optimal way you could perform a bulk insert on many to many field in Django using a single line of code.

Use:

user.groups.add(administrators, managers)
    
Highlighted code sample.

Instead of:

user.groups.add(administrators)
    user.groups.add(managers)
    
Highlighted code sample.

2. Check if Django QuerySets is Empty

If you only need to know if the queryset is empty in Django:

Use:

groups = Group.objects.all()
    if groups.exists():
        # Do something...
    
Highlighted code sample.

Instead of:

groups = Group.objects.all()
    if groups:
        # Do something...
    
Highlighted code sample.

3. Count the Number of QuerySets Object Returned in Django

If you need to count the number of queryset objects returned in Django

Use:

users = User.objects.all()
    users.count()
    
    # Or in template...
    {{ users.count }}
    
Highlighted code sample.

Instead of:

users = User.objects.all()
    len(users)
    
    # Or in template...
    {{ users|length }}
    
Highlighted code sample.

4. Access Foreign Key Values in Django

Assuming you have a model for blog posts with a foreign key to author, if you only need the ID of the Foreign Key:

Use:

post.author_id
    
Highlighted code sample.

Instead of:

post.author.id
    
Highlighted code sample.

This method works because since we have a foreign key named author, Django automatically stores the primary key in the property author_id, whereas the author property will be stored in a lazy database reference.

This means that if you access the ID via the author instance, using the method post.author.id, it will cause an additional query.

5. Reduce Query Count when Accessing Foreign Key in Django

Here's how to reduce the query count when accessing foreign key in Django:

Use:

post = Post.objects.select_related('author').first()
      
    # Select the Post and the Author in a single query
    name = post.author.name
    
Highlighted code sample.

Instead of:

post = Post.objects.first()  # Select the Post
    name = post.author.name  # Additional query to select the Author
    
Highlighted code sample.

6. Select Only What You Need

Let's say the Post model has 20 fields and you want to create a view to display just a summary, with the title, date and content:

Use:

# views.py
    # If you don't need the model instance, go for:
    posts = Post.objects.values('title', 'date', 'content')  # Returns a dict
    
    # If you still need to access some instance methods, use:
    posts = Post.objects.only('number', 'date', 'value')  # Returns a queryset
    
    # posts.html
    <table>
      {% for post in posts %}
        <tr>
          <td>{{ post.number }}</td>
          <td>{{ post.date }}</td>
          <td>{{ post.value }}</td>
        </tr>
      {% endfor %}
    </table>
    
Highlighted code sample.

Instead of:

# views.py
    posts = Post.objects.all()
    
    # posts.html
    <table>
      {% for post in posts %}
        <tr>
          <td>{{ post.number }}</td>
          <td>{{ post.date }}</td>
          <td>{{ post.value }}</td>
        </tr>
      {% endfor %}
    </table>
    
Highlighted code sample.

7. Bulk Updates

Here's how to perform a bulk update efficiently in Django:

Use:

Post.objects.update(publish=False)
    
Highlighted code sample.

Instead of:

posts = Post.objects.all()
    for post in posts:
        post.publish = False
        post.save()
    
Highlighted code sample.

Wrap Off

These seven simple tips will help make your Django query optimizations more efficient and improve the performance of your application.

I recommend keeping these in mind when working on a new application.

If you learned from this tutorial, or it helped you in any way, please consider sharing and subscribing to our newsletter.

Please share this post and for more insightful posts on business, technology, engineering, history, and marketing, subscribe to our newsletter.

Get the Complete Code of Django and FastAPI Combo Tutorials on Github.

Connect with me.

Need an engineer on your team to grease an idea, build a great product, grow a business or just sip tea and share a laugh?