The Purpose of This Tutorial
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
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
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.
Dockerfile1RUN 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
Here’s what I needed to install for an Alpine image to get it working:
Dockerfile1RUN 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?
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
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
Add '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]
Rebuild your container
We need to rebuild the Docker container now since we introduced new dependencies. If you’re using docker-compose:
shell1docker-compose down
2docker-compose up -d --build
If all is well, you should see pygraphviz installed successfully in your build logs.
Testing graph models
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.
Learn more
To learn more, check out the full documentation for django-extensions on Read the Docs.