Add Notion as your Django database in 8 minutes 🕯️

Updated: Fri 03 May 2024

Notion is a surprisingly good choice for adding a simple database when using Django. It's:

  • quick
  • free
  • helps you create a product that needs some state fast.
  • simple to see your data and edit it because you are just using Notion.
  • shareable. You can share your database and let them edit it too. This is also useful for when working with non-technical customers.
  • easy. You don't have to spend time setting up a database (you can add Postgres later).

I'll show your how to add Notion as your Django database in less than 8 minutes.

This follows my previous guide and talk at Django London 🇬🇧 on using Google sheets as a database that I gave in November.

Here's what we'll make:


Let's begin 🛫

Optional video tutorial (featuring me) below 📽️:


0. Setup the Django project that we'll connect to our Notion database

Install the necessary packages

pip install django python-dotenv notion-client
django-admin startproject core .
python manage.py startapp sim

We'll be using the notion client as a wrapper for the Notion API.

Register your app in your settings.py file

  • Add 'sim' to the INSTALLED_APPS list in the settings.py file:
INSTALLED_APPS = [
    # ...
    'sim',
    # ...
]

1. Add your Notion API key to the Django project

  • Go to the Notion integrations page and click "Create a new integration"
  • Go to capabilities and tick the box saying "Read user information including email addresses"
  • Enter a name for the integration and click "Submit"
  • Copy the "Internal Integration Token"

  • Create a new file called .env in the core directory

  • Add the following line to the .env file, replacing <your-token> with the token you copied from Notion:
NOTION_TOKEN=<your-token>
  • Add the following line to the top of the settings.py file to load the environment variables:
from dotenv import load_dotenv
import os


load_dotenv()

Test your connection to the Notion API

Open your Django shell:

python manage.py shell

Run the following commands:

import os
from notion_client import Client

notion = Client(auth=os.environ["NOTION_TOKEN"])
list_users_response = notion.users.list()
print(list_users_response)

You should see a list of users in your Notion workspace that looks something like this:

{
"object": "list",
"results": [
{
"object": "user",
"id": "a1b2c3d4-1234-5678-90ab-cdef12345678",
"type": "person",
"name": "John Doe",
"avatar_url": "https://example.com/image.png"
}
],
"next_cursor": null,
"has_more": false
}

See here for:

  • the notion_client library documentation: https://github.com/ramnes/notion-sdk-py
  • the full list of API commands (which the notion_client library wraps): https://developers.notion.com/reference/intro
Troubleshooting: I get an error like "AttributeError: 'str' object has no attribute 'logger'. Did you mean: 'lower'?" The notion_client Client requires the `auth` keyword argument, i.e., `Client(auth=os.environ["NOTION_TOKEN"])`

2. Connect your Notion database to Django

Connect your database to an integration

To use an API with a certain database, you need to give that database permission to work with your API integration. This isn't done when you create the API token, but you can find how to do it in the instructions.

Here's how to let your API integration access a database:

  1. Open the database you want in Notion
  2. Look for a menu with three dots (•••) at the top-right of the page and click it.
  3. From the menu that appears, choose "Add connections."
  4. Pick your API integration from the list that shows up.

Add your Notion database ID to the Django project

  • Append the following line to the .env file, replacing <your-token> with the token you copied from Notion:
NOTION_DATABASE_ID=<your-token>

Get your Notion database ID to query with Django

To find a database ID, navigate to the database URL in your Notion workspace. The ID is the string of characters in the URL that is between the slash following the workspace name (if applicable) and the question mark. The ID is a 32 characters alphanumeric string.

Oddly, there's no clear way to list all databases and their IDs using the Notion API. The simplest way is to get the database id from the database's URL

You can get this by:

  1. clicking 'share'
  2. copying the link to your database
  3. finding the id in the link

Here's a link to show which part of the url is your database id: https://developers.notion.com/reference/retrieve-a-database

Test your connection to your Notion database using Django

Back to the Django shell, run the following commands:

import os
from notion_client import Client
notion = Client(auth=os.environ["NOTION_TOKEN"])
notion.databases.query(os.environ["NOTION_DATABASE_ID"])

3. Render your Notion data in a Django template

Connect your urls to your views

  • Update the sim/urls.py file:
from django.urls import path
from . import views


urlpatterns = [
    path('', views.index, name='index'),
]

  • Update the core/urls.py file:
from django.contrib import admin
from django.urls import include, path


urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('sim.urls')),
]

Create a template to render your Notion data to HTML

  • Create a new directory called templates in the sim directory
  • Create a new file called index.html in the templates directory
  • Update the index.html file:
<!DOCTYPE html>
<html>
<head>
    <title>Your applicants</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f4f4f4;
        }
        .container {
            width: 80%;
            margin: 20px auto;
            background: white;
            padding: 20px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }
        .employee-row {
            display: flex;
            align-items: center;
            background-color: #fff;
            margin-bottom: 10px;
            padding: 10px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        a {
            text-decoration: none;
            color: #000;
        }
        .employee-row:hover {
            background-color: #f9f9f9;
        }
        .profile-info {
            display: flex;
            align-items: center;
            margin-right: 20px;
        }
        .profile-info img {
            width: 80px;
            height: 80px;
            border-radius: 40px;
            margin-right: 15px;
            object-fit: cover;
        }
        .employee-details {
            display: flex;
            flex-direction: column;
        }
        .employee-details > div {
            margin-bottom: 5px;
        }
    </style>
</head>
<body>
<div class="container">
    {% for row in rows %}
    <a class="employee-row" href="{{ row.properties.profile_url.url }}" target="_blank">
        <div class="profile-info">
            <img src="{{ row.properties.photo.files.0.file.url }}" alt="{{ row.properties.name.title.0.plain_text }}">
        </div>
        <div class="employee-details">
            <div><strong>{{ row.properties.name.title.0.plain_text }}</strong></div>
            <div>{{ row.properties.role.rich_text.0.text.content }}</div>
            <div>{{ row.properties.description.rich_text.0.text.content }}</div>
        </div>
    </a>
    {% endfor %}
</div>
</body>
</html>

Create a view to send your Notion API as context to the Django template

  • Update the sim/views.py file:
from django.shortcuts import render
from notion_client import Client
import os


def index(request):
    notion = Client(auth=os.environ['NOTION_TOKEN'])
    data = notion.databases.query(os.environ.get('NOTION_DATABASE_ID'))
    return render(request, 'index.html', {'rows': data['results']})

Run the Django server

python manage.py runserver

4. Add data to your Notion database

Now we need some data to your database in Notion.

Feel free to add your own fields to the database and update the template to use them. To work with the variables I added to the Django template, you need to add the following properties to your database:

  • name (title) (Make sure it's lowercase)
  • photo (file)
  • role (rich text)
  • description (rich text)
  • profile_url (url)

Here's the data I added to my database if you want to copy it:

name,photo,role,description,profile_url
Andrew Michs, ,Software Developer,"Translate the arcane mutterings of stakeholder meetings into elegant code, presumably using some form of dark magic (also known as JavaScript). Work in a team that believes 'Agile' is a type of yoga. Required: an undying love for debugging at 3 AM.",https://www.photondesigner.com
Kelly Conway, ,Marketing Manager,"Cut through the digital noise with the sharp blade of your wit, crafting campaigns that might actually be read. Analyze trends with the enthusiasm of a cat watching a documentary on bird migration. Bonus points if you can say 'synergy' without cringing.",https://www.photondesigner.com
Hella Paulson, ,Human Resources Coordinator,Divine the future of candidates from the entrails of their CVs. Spread joy and policies with equal fervor. Experience in resolving coffee machine disputes preferred.,https://www.photondesigner.com
Teshra Coda, ,Graphic designer,"Transform client 'feedback' into visual gold, often by guessing what they meant by 'make it pop'. Must enjoy spelunking in the caverns of Adobe Creative Suite. Warning: Exposure to Comic Sans may occur.",https://www.photondesigner.com

5. View the Notion data in your Django template

Troubleshooting: I get the error "TemplateDoesNotExist at /" Make sure you have: 1. the `templates` directory in the `sim` directory 2. the `index.html` file is in the `templates` directory 3. Added 'sim' to the `INSTALLED_APPS` list in the `settings.py` file (See above) 4. are visiting the correct URL (See above)

Edit your Notion database and see the changes in your Django template

With your Django app now connected to your Notion database, any changes you make in Notion will reflect in your Django template.


Congrats! You've connected your Notion database to your Django project

You've combined Notion and Django, creating a flexible database 🌟.

Let's go bigger: imagine allowing your users to contribute and edit content. Envision the potential enhancements to your app. Users could add new items or tweak existing ones.

You could create a digital gallery, or perhaps a platform similar to Instagram that supports video uploads.

Build your Django frontend even faster

I want to release high-quality products as soon as possible. Probably like you, I want to make my Django product ideas become reality as soon as possible.

That's why I built Photon Designer - an entirely visual editor for building Django frontend at the speed that light hits your eyes. Photon Designer outputs neat, clean Django templates.

Let's get visual.

Do you want to create beautiful django frontends effortlessly?
Click below to book your spot on our early access mailing list (as well as early adopter prices).
Copied link to clipboard 📋