Add a headless CMS to Python/Django in 5 minutes

In this article, we will show you how you can use Storyblok using Python, Django, and Jinja2. At the end of this article, you will have a Python application which renders components filled with data from Storyblok.

During this article, for example, we will use following JSON which comes from the Storyblok API to render our first story:

$ curl
  "story": {
    "name": "home",
    "content": {
      "component": "root",
      "body": [
          "component": "teaser",
          "headline": "Easy - isn't it?"
    "slug": "home",
    "full_slug": "home"

1. Install the Storyblok CLI

npm install storyblok -g

2. Bootstrap your python project

We’re going to use the framework Django for this example as many the python developers are already familiar with this - if you’re not - we’re only using some basics of it - you can of course also have a look at the Django documentation.

storyblok select

You will be asked few questions - you can answer them like we did in the screenshot below.

Bootstrap your python project with storyblok

3. Start your local development environment

You can now fire up your local environment - Make sure Django and Jinja2 are installed:

pip install django
pip install jinja2

And start your local Python server on port 8000. It is also recommended that you use virtualenv to separate the Storyblok environment from other Python projects.

cd ./YOUR_PROJECT_NAME && python migrate && python runserver

As Django suggest to not serve files with Django - so we’re using gulp as a proxy for the python server and also serve the static assets like css and js files this way - in production your normal webserver (Nginx, Apache, …) will serve those files.

npm install && gulp

You should now have two terminal windows running - one for the Python server and the other one for the static files with gulp using the port 3000.

Local environment ready to create your website.

If you’re now visiting http://localhost:3000/ you should already see the following screen:

Python running and first call done

The boilerplate already has the read-only access token to one of our test spaces. It already does the GET request and loads a full story of that space and displays the component “teaser” for you. You can find the source of that component in the “teaser.html.j2”. In the “root.html.j2” we will simply iterate through the body property and include the components according to the loaded json.

4. Congrats.

You’ve now already loaded a story from Storybloks API and rendered two components. Let’s have a look how you can change the text of the component you already saw and create new components.

Configuring Storyblok

Now that you have successfully integrated Storyblok in your project let’s create a “Story” in your own Storyblok space.

Using the CLI:

  1. npm install -g storyblok
  2. storyblok quickstart

Using the Webinterface:

  1. Go to!/signup and do the signup
  2. Create a new Space.

Both ways will start with the quickstart which will guide you through your first time creating a component in Storyblok.

follow the quickstart

Exchange the private token

Copy your private token to receive the draft version of your content. The private token is a read-only token and can be found in the dashboard of your newly created space. Insert your token at the end of the “”.

# Storyblok configuration for your own space
  'HOME_SLUG': 'home'
Your own private token

Add a dev environment

After adding your own token from your Space to your project - we will have to also tell Storyblok where to find our dev environment. For this we will navigate to the Settings of a Space and add the URL http://localhost:3000/ as a new environment.

add a dev environment

The presentation layer for your component

The counter part to the component in Storyblok is right in your already downloaded python project. you can find the teaser.html.j2 in the /webapp/views/components/ folder. We’re using jinja2 for the templates - you can, of course, change this with any other templating engine you want. For this example that’s how the teaser.html.j2 looks like:

<div class="teaser">
  The _editable attribute makes the next
  DOM-element clickable so the sidebar can
  show the right component.
  {{ blok._editable|safe }}
  <div class="teaser__inner">
      You can access every attribute you
      define in the schema in the blok variable
    {{ blok.headline }}
        You can create new components like this, to create your own set of components.

You see it’s nothing more then a plain html with a simple placeholder for the property headline. The only thing that differences to a “normal” HTML is the {{blok._editable|safe}} - in the draft modus of your component we will add a comment into your JSON so we can make a reference between your component and the sidebyside editor you will see in the next steps - combined with the script which is already included at the bottom of the /webapp/views/index.html.j2.

Well done!

Try out to insert a text and click “Save”. Your component should now be updated with the new content. Next step is to repeat the steps above to configure more components. All you now need to do is to create those new components as Jinja2/HTML components. As you can see the Components in the right side are clickable - all you need to add is {{blok._editable|safe}} in your new component - as we already did in the “teaser.html.j2”.

Hello from Storyblok

You can also create grid and column components which can nest other components with the schema type “components”. A root component is such a component which has other components nested - e.g. news-entry, portfolio-item, … .

If you need additional help - you can chat with us using the chat symbol at the right bottom corner.

Components in this Tutorial

Component NameComponent Use
rootholder for all nested components - only has a property of the typ "components".
teasercontains the property "headline" so the components headline can be edited in the SideBySide Editor.

Next: Learn about components

How thinking in components can increase your productivity? Components are units of code that are nestable, reusable and decoupled. They help you to don’t repeat yourself writing the same functionality or HTML tags multiple times. They ease the process of thinking because…

More to read...

About the author

Dominik Angerer

A web performance specialist and perfectionist. After working for big agencies as a full stack developer he founded Storyblok. He is also an active contributor to the open source community and one of the organizers of Stahlstadt.js.