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.
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.
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
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.
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.
Unfortunately, for Buster or Slim images I’m not positive exactly what packages are required. I believe you should be good with just
python3-dev but I haven’t tested it so don’t take my word for it.
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).
pygraphviz to your requirements file however you see fit.
'django_extensions' to the
INSTALLED_APPS setting in your
project/settings.py file if you haven’t already.
1INSTALLED_APPS = [ 2 # ... 3 'django_extensions', 4 # ... 5]
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.
Finally, test that the
graph_models feature is working as expected.
1docker-compose exec web python manage.py 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.
To learn more, check out the full documentation for django-extensions on Read the Docs.