The Purpose of This Tutorial Link to this heading

The django-extensions app includes a useful command line extension called graph_models for quickly generating graphical representations of your Django models. However, setting it up correctly with your app running in a Docker container isn’t so straightforward.

The documentation recommends installing the pygraphviz module which is a Python wrapper for the graphical visualization software, Graphviz.

As such, the Graphviz Linux package is a non-Python dependency for pygraphviz (along with a few other packages depending on the flavor of your image). If you’re developing your app in a Docker container, it’s unlikely these are installed by default.

The purpose of this quick guide is to clarify how to get the graph_models feature working despite this limitation.

Warning: I’m not a Docker expert. Just a humble Python developer who had to figure this out the hard way.

Quick note on packaging Link to this heading

First, we need to update our Dockerfile to automatically install the Graphviz Linux package during the image build process.

Before we do this, there’s one caveat: the packages you need to install may differ based on what flavor of Linux your image uses (so will the commands).

Alpine images require a handful of addtional installs because they only come with the essentials. Buster or Slim require less. For the base Python image, just installing Graphviz should work fine. You get the point.

Update your Dockerfile Link to this heading

Add the following to your Dockerfile for Debian-based images. If you’re using a different Linux distro or alternate package manager, substitute the commands accordingly (Alpine uses apk).

FYI: this is the bare minimum you’ll need and will likely only be sufficient for base images. I’ll talk about some other packages you may need in a second.

1RUN apt-get -y update && apt-get -y install graphviz graphviz-dev

It’s worth noting that this RUN directive must come before the layer that installs your Python dependencies (with pip install requirements.txt, for example). Otherwise, your build will fail on the final step because pygraphviz needs Graphviz to be installed before it’s installed from pip.

Also, if you already have a layer that installs packages like this, use && to chain your commands and run them all in the same layer if possible. This should help reduce your image size.

Alpine example Link to this heading

Here’s what I needed to install for an Alpine image to get it working:

1RUN apk update \
2    && apk add pkgconfig graphviz graphviz-dev ttf-freefont gcc python3-dev musl-dev

With this setup, I was able to get the package installed but when I tried to generate a graph, the fonts would show up as empty boxes in the image. Adding ttf-freefont to the dependencies cleared this issue up.

Buster and Slim? Link to this heading

Unfortunately, for Buster or Slim images I’m not positive exactly what packages are required. I believe you should be good with just graphviz, graphviz-dev, gcc, and python3-dev but I haven’t tested it so don’t take my word for it.

Install Python and Django dependencies Link to this heading

Now it’s time to install the django-extensions app and pygraphviz module with your Python package manager of choice.

I recommend simply adding this to your requirements file so we only have to rebuild the containers once (as opposed to rebuilding with the Graphviz dependencies and installing the Python dependencies manually with pip in the container, then rebuilding again).

Add django-extensions and pygraphviz to your requirements file however you see fit.

Add to INSTALLED_APPS Link to this heading

Add 'django_extensions' to the INSTALLED_APPS setting in your project/ file if you haven’t already.

2    # ...
3    'django_extensions',
4    # ...

Rebuild your container Link to this heading

We need to rebuild the Docker container now since we introduced new dependencies. If you’re using docker-compose:

1docker-compose down
2docker-compose up -d --build

If all is well, you should see pygraphviz installed successfully in your build logs.

Testing graph models Link to this heading

Finally, test that the graph_models feature is working as expected.

1docker-compose exec web python graph_models -a -o myapp_models.png

The above command will output a .png file to the root directory of your project with your entire model structure visualized. You can also get more granular with it by limiting it to certain apps, excluding models, and more.

Learn more Link to this heading

To learn more, check out the full documentation for django-extensions on Read the Docs.